Skip to content
data-architecture logo

Data Architecture Skill

data-architecture

Single source of truth patterns, facts.ts structure, type safety, and data helper functions. Use when working with project data or adding new facts.

SKILL.md

Full skill instructions

Data Architecture Skill

Overview

This project uses a single source of truth pattern for all data. All personal information, project details, and configuration data is centralized in typed data files.

Core Principle: Single Source of Truth

Rule: Never hardcode personal data. Always reference data files.

// ❌ WRONG - Hardcoded data
const email = "[email protected]";
const name = "Omer Akben";

// ✅ CORRECT - Reference data file
import { facts } from "@/​data/​facts";
const email = facts.contact.email;
const name = facts.personal.name;
```typescript

## Data File Structure

### Primary Data Files

```typescript
src/​data/
├── facts.ts          # Personal info, skills, experience
├── projects.ts       # Project catalog with metadata
└── ...               # Other data files

src/​config/
└── assistantFaq.ts   # FAQ and intent libraries
```typescript

## facts.ts Architecture

**Location:** `src/​data/​facts.ts`

### Structure Overview

```typescript
export const facts = {
  personal: {
    name: string;
    title: string;
    location: LocationInfo;
    bio: string;
    tagline: string;
  },

  contact: {
    email: string;
    phone: string;
    github: string;
    linkedin: string;
    calendly: string;
  },

  professional: {
    experience: Experience[];
    education: Education[];
    skills: Skill[];
    certifications: Certification[];
    workAuthorization: WorkAuthorization; // Added 2025-11-02
  },

  preferences: {
    timezone: string;
    availability: string;
  }
};
```typescript

### Type Definitions

```typescript
interface LocationInfo {
  city: string;
  state: string;
  country: string;
  timezone: string;
}

interface Experience {
  id: string;
  company: string;
  position: string;
  startDate: string;
  endDate: string | 'Present';
  description: string;
  technologies: string[];
  achievements: string[];
}

interface Skill {
  id: string;
  name: string;
  category: SkillCategory;
  level: SkillLevel;
  yearsOfExperience: number;
}

interface WorkAuthorization {
  status: string;
  officialTitle: string;
  sponsorshipRequired: boolean;
  employmentRestrictions: boolean;
  eligibleEmployers: string;
  proofDocument: string;
  summary: string;
}
```typescript

### Work Authorization Data

**Added:** November 2, 2025
**Location:** `facts.professional.workAuthorization`

```typescript
workAuthorization: {
  status: "U.S. Permanent Resident (Green Card)",
  officialTitle: "Lawful Permanent Resident (LPR)",
  sponsorshipRequired: false,
  employmentRestrictions: false,
  eligibleEmployers: "Any U.S. employer",
  proofDocument: "Form I-551 (Permanent Resident Card)",
  summary: "Authorized to work for any U.S. employer without restrictions or sponsorship requirements."
}
```typescript

**Usage:** AI agent references this when answering recruiter questions

## projects.ts Architecture

**Location:** `src/​data/​projects.ts`

### Structure

```typescript
export interface Project {
  id: string;
  slug: string;
  title: string;
  tagline: string;
  description: string;
  longDescription: string;
  technologies: Technology[];
  category: ProjectCategory;
  featured: boolean;
  showcase: boolean;
  liveUrl?: string;
  githubUrl?: string;
  imageUrl: string;
  metrics?: ProjectMetrics;
  testimonials?: Testimonial[];
}

export const projects: Project[] = [
  // Array of all projects
];
```typescript

### Helper Functions

```typescript
// Get projects by category
export function getProjectsByCategory(category: ProjectCategory): Project[] {
  return projects.filter(p => p.category === category);
}

// Get featured projects
export function getFeaturedProjects(): Project[] {
  return projects.filter(p => p.featured);
}

// Get project by slug
export function getProjectBySlug(slug: string): Project | undefined {
  return projects.find(p => p.slug === slug);
}

// Get all technologies used
export function getAllTechnologies(): Technology[] {
  const techSet = new Set<Technology>();
  projects.forEach(p => p.technologies.forEach(t => techSet.add(t)));
  return Array.from(techSet);
}
```typescript

### Usage Pattern

```typescript
import { projects, getFeaturedProjects, getProjectBySlug } from "@/​data/​projects";

// In component
const featured = getFeaturedProjects();
const project = getProjectBySlug(params.slug);
```typescript

## Type Safety Patterns

### 1. Const Assertions

```typescript
export const SKILL_CATEGORIES = [
  'Frontend',
  'Backend',
  'DevOps',
  'AI/​ML',
] as const;

export type SkillCategory = typeof SKILL_CATEGORIES[number];
// Type is: 'Frontend' | 'Backend' | 'DevOps' | 'AI/​ML'
```typescript

### Benefits

- Autocomplete in IDE
- Type checking
- Single source for both runtime and types

### 2. Branded Types

```typescript
type ProjectId = string & { readonly __brand: 'ProjectId' };
type UserId = string & { readonly __brand: 'UserId' };

// Prevents mixing up IDs
function getProject(id: ProjectId) { /​* ... */ }
function getUser(id: UserId) { /​* ... */ }

// TypeScript error: types are incompatible
const projectId: ProjectId = 'proj_123' as ProjectId;
const userId: UserId = 'user_456' as UserId;
getProject(userId); // ❌ Error!
```typescript

### 3. Discriminated Unions

```typescript
type Education =
  | { type: 'degree'; university: string; degree: string; major: string; }
  | { type: 'bootcamp'; program: string; completion: string; }
  | { type: 'certification'; name: string; issuer: string; };

function formatEducation(edu: Education): string {
  switch (edu.type) {
    case 'degree':
      return `${edu.degree} in ${edu.major} from ${edu.university}`;
    case 'bootcamp':
      return `${edu.program}`;
    case 'certification':
      return `${edu.name} by ${edu.issuer}`;
  }
}
```typescript

## Zod Validation Integration

### Schema Definitions

**Location:** `src/​lib/​agent-tools/​schemas.ts`

```typescript
import { z } from 'zod';

export const ContactSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  company: z.string().optional(),
  message: z.string().min(10),
});

export type Contact = z.infer<typeof ContactSchema>;
```typescript

### Runtime Validation

```typescript
// API route handler
export async function POST(request: Request) {
  const body = await request.json();

  // Validate with Zod
  const result = ContactSchema.safeParse(body);

  if (!result.success) {
    return Response.json({
      success: false,
      error: result.error.format(),
    }, { status: 400 });
  }

  // Type-safe data access
  const { name, email, company, message } = result.data;
  // ...
}
```typescript

### Benefits of Zod

- Runtime validation
- Type inference from schemas
- Detailed error messages
- Parse, transform, and validate in one step

## AI Agent Data Integration

### Knowledge Base

**Location:** `src/​lib/​agent-knowledge-base.ts`

The AI agent consumes data from facts.ts:

```typescript
import { facts } from '@/​data/​facts';

export const agentKnowledgeBase = `
# Core Identity
Name: ${facts.personal.name}
Title: ${facts.personal.title}
Location: ${facts.personal.location.city}, ${facts.personal.location.state}

# Work Authorization
Status: ${facts.professional.workAuthorization.status}
Sponsorship Required: ${facts.professional.workAuthorization.sponsorshipRequired}

# Skills
${facts.professional.skills.map(s => `- ${s.name} (${s.level})`).join('\n')}

# Contact
Email: ${facts.contact.email}
LinkedIn: ${facts.contact.linkedin}
`;
```typescript

### Benefits

- Single source ensures consistency
- Updates to facts.ts automatically flow to AI
- No hardcoded data in agent prompts

### Tool Implementations

AI agent tools reference data files:

```typescript
// src/​app/​api/​tools/​get-contact/​route.ts
import { facts } from '@/​data/​facts';

export async function POST() {
  return Response.json({
    success: true,
    data: {
      email: facts.contact.email,
      linkedin: facts.contact.linkedin,
      github: facts.contact.github,
      calendly: facts.contact.calendly,
    }
  });
}
```typescript

## Adding New Data

### Step 1: Update Type Definition

```typescript
// src/​data/​facts.ts
interface Facts {
  personal: PersonalInfo;
  contact: ContactInfo;
  professional: ProfessionalInfo;
  newSection: NewSectionType; // Add new section
}
```typescript

### Step 2: Add Data

```typescript
export const facts: Facts = {
  // ... existing data
  newSection: {
    field1: 'value1',
    field2: 'value2',
  }
};
```typescript

### Step 3: Update AI Knowledge Base

```typescript
// src/​lib/​agent-knowledge-base.ts
export const agentKnowledgeBase = `
...existing content...

# New Section
${facts.newSection.field1}
${facts.newSection.field2}
`;
```typescript

### Step 4: Add Tests

```typescript
// src/​data/​facts.test.ts
describe('facts.newSection', () => {
  it('should have required fields', () => {
    expect(facts.newSection.field1).toBeDefined();
    expect(facts.newSection.field2).toBeDefined();
  });
});
```typescript

## Data Validation Patterns

### 1. Email Validation

```typescript
import { z } from 'zod';

const EmailSchema = z.string()
  .email('Invalid email format')
  .toLowerCase()
  .trim();

// Usage
const email = EmailSchema.parse('[email protected]');
// Result: '[email protected]'
```typescript

### 2. URL Validation

```typescript
const UrlSchema = z.string()
  .url('Invalid URL format')
  .refine(url => url.startsWith('https://'), {
    message: 'URL must use HTTPS'
  });
```typescript

### 3. Date Validation

```typescript
const DateSchema = z.string()
  .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be YYYY-MM-DD')
  .refine(date => !isNaN(Date.parse(date)), {
    message: 'Invalid date'
  });
```typescript

### 4. Enum Validation

```typescript
const SkillLevelSchema = z.enum([
  'Beginner',
  'Intermediate',
  'Advanced',
  'Expert'
]);

type SkillLevel = z.infer<typeof SkillLevelSchema>;
```typescript

## Helper Function Patterns

### 1. Filter Helpers

```typescript
// Get items by property
export function getByCategory<T extends { category: string }>(
  items: T[],
  category: string
): T[] {
  return items.filter(item => item.category === category);
}

// Get items by multiple criteria
export function getByFilters<T>(
  items: T[],
  filters: Partial<T>
): T[] {
  return items.filter(item => {
    return Object.entries(filters).every(([key, value]) => {
      return item[key as keyof T] === value;
    });
  });
}
```typescript

### 2. Sort Helpers

```typescript
// Sort by date
export function sortByDate<T extends { date: string }>(
  items: T[],
  order: 'asc' | 'desc' = 'desc'
): T[] {
  return [...items].sort((a, b) => {
    const dateA = new Date(a.date).getTime();
    const dateB = new Date(b.date).getTime();
    return order === 'asc' ? dateA - dateB : dateB - dateA;
  });
}

// Sort by property
export function sortBy<T, K extends keyof T>(
  items: T[],
  key: K,
  order: 'asc' | 'desc' = 'asc'
): T[] {
  return [...items].sort((a, b) => {
    if (a[key] < b[key]) return order === 'asc' ? -1 : 1;
    if (a[key] > b[key]) return order === 'asc' ? 1 : -1;
    return 0;
  });
}
```typescript

### 3. Transform Helpers

```typescript
// Group by property
export function groupBy<T, K extends keyof T>(
  items: T[],
  key: K
): Record<string, T[]> {
  return items.reduce((acc, item) => {
    const groupKey = String(item[key]);
    if (!acc[groupKey]) acc[groupKey] = [];
    acc[groupKey].push(item);
    return acc;
  }, {} as Record<string, T[]>);
}

// Map to lookup object
export function toMap<T extends { id: string }>(
  items: T[]
): Record<string, T> {
  return items.reduce((acc, item) => {
    acc[item.id] = item;
    return acc;
  }, {} as Record<string, T>);
}
```typescript

## Testing Data Integrity

### Unit Tests

```typescript
// src/​data/​facts.test.ts
import { facts } from './​facts';

describe('facts.ts data integrity', () => {
  it('should have valid email', () => {
    expect(facts.contact.email).toMatch(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/);
  });

  it('should have all required skills', () => {
    expect(facts.professional.skills.length).toBeGreaterThan(0);
    facts.professional.skills.forEach(skill => {
      expect(skill.name).toBeTruthy();
      expect(skill.category).toBeTruthy();
      expect(skill.level).toBeTruthy();
    });
  });

  it('should have valid work authorization', () => {
    const { workAuthorization } = facts.professional;
    expect(workAuthorization.status).toBeTruthy();
    expect(typeof workAuthorization.sponsorshipRequired).toBe('boolean');
    expect(typeof workAuthorization.employmentRestrictions).toBe('boolean');
  });
});
```typescript

### Zod Schema Tests

```typescript
import { ContactSchema } from './​schemas';

describe('ContactSchema validation', () => {
  it('should accept valid contact', () => {
    const valid = {
      name: 'John Doe',
      email: '[email protected]',
      message: 'Hello, this is a test message.',
    };

    const result = ContactSchema.safeParse(valid);
    expect(result.success).toBe(true);
  });

  it('should reject invalid email', () => {
    const invalid = {
      name: 'John Doe',
      email: 'not-an-email',
      message: 'Hello, world',
    };

    const result = ContactSchema.safeParse(invalid);
    expect(result.success).toBe(false);
  });
});
```typescript

## Common Mistakes

### Mistake 1: Hardcoding Data

```typescript
// ❌ WRONG
function Header() {
  return <h1>Omer Akben - AI Engineer</​h1>;
}

// ✅ CORRECT
import { facts } from '@/​data/​facts';

function Header() {
  return <h1>{facts.personal.name} - {facts.personal.title}</​h1>;
}
```typescript

### Mistake 2: Inconsistent Data Format

```typescript
// ❌ WRONG - Different date formats
{
  startDate: '2024-01-01',
  endDate: 'January 2024',
}

// ✅ CORRECT - Consistent ISO format
{
  startDate: '2024-01-01',
  endDate: '2024-01-31',
}
```typescript

### Mistake 3: No Validation

```typescript
// ❌ WRONG - Assumes data is valid
const user = JSON.parse(request.body);
saveUser(user);

// ✅ CORRECT - Validate first
const result = UserSchema.safeParse(JSON.parse(request.body));
if (result.success) {
  saveUser(result.data);
}
```typescript

## Data Update Checklist

When adding or updating data:

- [ ] Update type definitions first
- [ ] Add/​modify data in facts.ts or projects.ts
- [ ] Update AI knowledge base if needed
- [ ] Add helper functions if beneficial
- [ ] Write unit tests for new data
- [ ] Verify AI agent responses still accurate
- [ ] Check that related tools still work
- [ ] Update documentation if structure changed

## Quick Reference

```typescript
// Import data
import { facts } from '@/​data/​facts';
import { projects, getProjectBySlug } from '@/​data/​projects';

// Access data
const email = facts.contact.email;
const name = facts.personal.name;
const project = getProjectBySlug('portfolio');

// Validate with Zod
const result = Schema.safeParse(data);
if (result.success) {
  // Use result.data
}

// Helper pattern
export function getFiltered<T>(items: T[], predicate: (item: T) => boolean): T[] {
  return items.filter(predicate);
}
```typescript

## Related Files

- `src/​data/​facts.ts` - Single source of truth for personal data
- `src/​data/​projects.ts` - Project catalog with helpers
- `src/​lib/​agent-knowledge-base.ts` - AI agent data integration
- `src/​lib/​agent-tools/​schemas.ts` - Zod validation schemas
- `src/​config/​assistantFaq.ts` - FAQ and intent libraries

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View