Skip to content
Back to skills

Feature Structure

ASecurity

How to organize features in LivestockAI

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
developmenttypescriptgodatabase

Security analysis

A100/100

Scanned February 10, 2026

npx -y skills add majiayu000/claude-skill-registry --skill feature-structure --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Feature Structure?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Feature Structure
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-feature-structure/badge)](https://www.skillsdirectory.com/skills/majiayu000-feature-structure)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Feature Structure
description: How to organize features in LivestockAI
---

# Feature Structure

Each major feature in LivestockAI has its own directory in `app/features/`.

## Directory Layout

```
app/features/batches/
├── server.ts        # Server functions (createServerFn)
├── service.ts       # Pure business logic
├── repository.ts    # Database operations
├── types.ts         # TypeScript interfaces
├── constants.ts     # Feature constants
└── index.ts         # Public exports
```

## File Purposes

### server.ts

Server functions that handle auth, validation, and orchestration:

```typescript
export const createBatchFn = createServerFn({ method: 'POST' })
  .inputValidator(schema)
  .handler(async ({ data }) => {
    const session = await requireAuth()
    const error = validateBatchData(data)
    if (error) throw new AppError('VALIDATION_ERROR')
    return insertBatch(db, data)
  })
```

### service.ts

Pure business logic functions (no side effects):

```typescript
export function calculateFCR(
  feedKg: number,
  weightGain: number,
): number | null {
  if (feedKg <= 0 || weightGain <= 0) return null
  return Math.round((feedKg / weightGain) * 100) / 100
}

export function validateBatchData(data: CreateBatchData): string | null {
  if (data.initialQuantity <= 0) return 'Quantity must be positive'
  return null
}
```

### repository.ts

Database operations only:

```typescript
export async function insertBatch(
  db: Kysely<Database>,
  data: BatchInsert,
): Promise<string> {
  const result = await db
    .insertInto('batches')
    .values(data)
    .returning('id')
    .executeTakeFirstOrThrow()
  return result.id
}
```

### types.ts

TypeScript interfaces:

```typescript
export interface CreateBatchData {
  farmId: string
  species: string
  initialQuantity: number
  costPerUnit: number
}

export interface BatchStats {
  mortality: { rate: number; total: number }
  feed: { totalKg: number; fcr: number | null }
  sales: { totalRevenue: number }
}
```

### index.ts

Public exports:

```typescript
export { createBatchFn, getBatchesFn } from './server'
export { calculateFCR, validateBatchData } from './service'
export type { CreateBatchData, BatchStats } from './types'
```

## Component Organization

UI components go in `app/components/`:

```
app/components/
├── ui/              # Base components (shadcn/ui)
├── dialogs/         # Create/edit modal dialogs
├── layout/          # Layout components
└── batches/         # Feature-specific components
    ├── batch-columns.tsx
    ├── batch-filters.tsx
    └── batches-skeleton.tsx
```

## Route Organization

Routes go in `app/routes/`:

```
app/routes/
├── _auth/           # Protected routes
│   ├── batches/
│   │   ├── index.tsx
│   │   └── $batchId.tsx
│   └── dashboard.tsx
└── index.tsx        # Public landing
```

## Related Skills

- `three-layer-architecture` - Layer responsibilities
- `tanstack-router` - Route organization
- `tanstack-start` - Server function patterns

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.