Feature Modules
How code is organized - everything for a feature lives together
TL;DR: All code for a feature lives in
/src/features/name/. Queries, actions, validation, types, UI - one folder.
The Problem This Solves
Traditional projects scatter code everywhere:
- Database queries in
/models/ - API routes in
/api/ - Components in
/components/ - Types in
/types/
To understand "clients", you jump between 5 folders. To add a field, you edit 8 files across the codebase.
The Straktur Way
Everything for a feature lives together:
src/features/clients/
├── queries.ts # Read from database (list, get, search)
├── actions.ts # Write to database (create, update, delete)
├── validation.ts # Input schemas (shared between API and forms)
├── types.ts # TypeScript types
├── index.ts # Public exports (safe for browser)
├── server.ts # Server-only exports (database access)
└── ui/ # Feature-specific components
├── ClientCard.tsx
└── ClientForm.tsxWhy this matters: When you say "add invoices feature", AI creates this exact structure. When you say "add field to clients", AI knows exactly which files to touch.
Concrete Example: Clients
The Clients feature lets you manage companies in your CRM. Here's how the code maps to what users see:
| User action | Code location | What happens |
|---|---|---|
Opens /clients page | queries.ts → listClients() | Fetches all clients for this organization |
| Clicks on a client | queries.ts → getClient(id) | Fetches single client with contacts |
| Fills the form | validation.ts → clientSchema | Validates input before saving |
| Clicks "Save" | actions.ts → updateClient() | Updates database record |
The Two Entry Points
Features have two exports to respect Next.js client/server boundary:
index.ts - Safe for browser (React components, hooks, types)
// ✅ Import in Client Components
import { ClientCard, clientSchema } from "@/features/clients"server.ts - Server only (database access)
// ✅ Import in Server Components, API routes
import { listClients, createClient } from "@/features/clients/server"Never import server.ts in Client Components - it will break your build.
What This Means for Your Prompts
| You say... | AI does... |
|---|---|
| "Add invoices feature" | Creates /src/features/invoices/ with all files |
| "Add due_date field to invoices" | Edits validation.ts, types.ts, queries.ts, actions.ts |
| "Copy clients pattern for invoices" | Replicates the exact structure |
Built-in Features
Beyond the module structure, Straktur gives you several ready-to-use features you can wire into any entity.
Internationalization (i18n)
Your app supports multiple languages out of the box using next-intl.
How it works:
- Each user has a preferred locale stored in the database (not in the URL)
- Translation files live in
messages/en.jsonandmessages/pl.json - English is the base — other languages overlay on top. Missing keys fall back to English automatically
- Supports plurals and interpolation via ICU Message Format (
{count, plural, one {# item} other {# items}})
Where translations are used:
- All page content, labels, and buttons
- Navigation and breadcrumbs
- DataTable column headers (via factory function pattern)
- Transactional emails (sent in the recipient's language)
- Dictionary value labels
For your prompts:
| You say... | AI does... |
|---|---|
| "Add Polish translations for invoices" | Adds keys to messages/pl.json matching the English structure |
| "Make the invoices page translatable" | Wraps strings with useTranslations(), adds keys to both language files |
Comments System
Add comments to any entity — clients, invoices, orders, anything. It's a generic, plug-and-play module.
What's included:
CommentsSectioncomponent — drop it into any detail page- Plain text input with Cmd+Enter to submit
- Avatars and relative timestamps
- Delete your own comments (admins can delete any)
DataTableIndicatorBadge— shows comment count as a small badge in table columns
How to use it:
import { CommentsSection } from "@/features/comments"
<CommentsSection entityType="invoice" entityId={invoice.id} />That's it. The component handles fetching, creating, and deleting comments. The database schema, validation, and API router are already set up.
| You say... | AI does... |
|---|---|
| "Add comments to invoices" | Adds CommentsSection to the invoice detail page |
| "Show comment count in the invoices table" | Adds DataTableIndicatorBadge to the primary column |
Rich Text Editor
A Tiptap-based WYSIWYG editor for when plain text inputs aren't enough. Available for any text field — descriptions, notes, attributes.
What it supports:
- Bold, italic
- Bullet lists
- Placeholder text
Components:
RichTextEditor— the editable input (stores HTML)Markdown— read-only renderer for saved content (renders HTML safely with sanitization)
Airtable Migration
Two AI-powered skills to move your existing Airtable data into Straktur:
Step 1: Discover — Run /airtable-discover and point it at your Airtable base. It analyzes:
- All tables, fields, and field types
- Relationships between tables
- Data patterns, validation rules, and edge cases
- Generates a detailed
AIRTABLE_REPORT.mdwith mapping recommendations
Step 2: Import — Run /airtable-import with the generated report. It creates:
- Per-entity migration scripts
- Proper type mapping (Airtable field types → Drizzle columns)
- Relationship handling and data transformation
You don't need to know the Airtable API or write migration code — the AI handles the mapping.
| You say... | AI does... |
|---|---|
| "Analyze my Airtable base" | Runs discover, generates mapping report |
| "Generate migration scripts from the report" | Creates runnable TypeScript migration scripts |
Related
- Add New Feature - Step-by-step guide
- Add Field to Entity - Checklist for adding fields