From ja
DDD component architecture for Vue/Nuxt projects — folder structure, naming conventions, translation keys, and component organisation. Use when creating components, choosing file paths, naming files, structuring translations, or organising domain folders.
npx claudepluginhub josephanson/claude-plugin --plugin jaThis skill uses the workspace's default tool permissions.
Domain-driven folder structure and conventions for Vue/Nuxt component organisation. Apply when creating, moving, or renaming components and translation keys.
Provides Ktor server patterns for routing DSL, plugins (auth, CORS, serialization), Koin DI, WebSockets, services, and testApplication testing.
Conducts multi-source web research with firecrawl and exa MCPs: searches, scrapes pages, synthesizes cited reports. For deep dives, competitive analysis, tech evaluations, or due diligence.
Provides demand forecasting, safety stock optimization, replenishment planning, and promotional lift estimation for multi-location retailers managing 300-800 SKUs.
Domain-driven folder structure and conventions for Vue/Nuxt component organisation. Apply when creating, moving, or renaming components and translation keys.
Path: components/[Domain]/[Feature]/[Function]/
File: [Name].vue (short names, Nuxt auto-generates full path prefix)
Kebab folders — Nuxt handles PascalCase resolution.
patient-care, records, inventory, catalog, calendar, reporting, settings)plans, laboratory)form, list, card, chart, dialog, menu)| Function | Purpose |
|---|---|
form/, form/fields | inputs, fieldsets, wizards |
list/ | tables, rows, grids |
card/ | summaries, widgets |
chart/ | visualisations, graphs |
dialog/ | modals, drawers |
menu/ | context menus, dropdowns |
| Path | Filename | Nuxt Component Name |
|---|---|---|
patient-care/plans/list/ | Active.vue | PatientCarePlansListActive |
patient-care/laboratory/card/ | Result.vue | PatientCareLaboratoryCardResult |
inventory/stock/actions/ | Adjust.vue | InventoryStockActionsAdjust |
form/ only when reused across multiple dialogs or contextsStatusBadge) — base/ or ui/index.ts) in domain folders — direct imports onlyBefore creating, verify:
Active.vue, Result.vue, Adjust.vueMain.vue, Default.vue, Component.vueform/, not dialog/Translation keys follow the same structure as file paths. Use dots instead of hyphens.
Path: pages.[domain].[feature].[function].*
Folder path to translation path:
components/inventory/stock-locations/ — pages.inventory.stock.locationscomponents/patient-care/plans/ — pages.patientCare.plansStructure:
{
"pages": {
"inventory": {
"stock": {
"locations": {
"list": {
"header": "Stock Locations",
"createButton": "Add Location",
"filters": { "searchPlaceholder": "Search locations..." }
},
"form": {
"createTitle": "Create Stock Location",
"editTitle": "Edit Stock Location",
"nameLabel": "Name",
"cancel": "Cancel",
"validation": { "nameRequired": "Name is required" }
},
"toast": {
"create": {
"success": "Stock location created",
"error": "Failed to create"
},
"edit": {
"success": "Stock location updated",
"error": "Failed to update"
},
"delete": {
"success": "Stock location deleted",
"error": "Failed to delete"
}
}
}
}
}
}
}
Usage in components:
// Single translation variable scoped to feature
const t = useTranslation('pages.inventory.stock.locations')
// Access nested keys via dot notation
t('list.header') // "Stock Locations"
t('list.createButton') // "Add Location"
t('form.nameLabel') // "Name"
t('form.validation.nameRequired') // "Name is required"
t('toast.create.success') // "Stock location created"
t('toast.edit.error') // "Failed to update"
Function categories match component folders:
| Function | Purpose |
|---|---|
list | Headers, buttons, filters, column labels for list views |
form | Labels, titles, buttons, validation for forms |
toast | Success/error notification messages (nested by action: create, edit, delete) |
dialog | Dialog-specific text (if needed beyond form titles) |
| Scenario | Resolution |
|---|---|
| Component used by 2+ domains equally | shared/[feature]/ |
| Form reused in multiple dialogs | Extract to [...]Form.vue, dialog imports form |
| Simple form in single dialog | Keep form inline within dialog component |
| Nested feature | patient-care/laboratory/results/ — PatientCareLaboratoryResults[Function].vue |
| Page-level component | pages/, not components/ |
| Composable | composables/[domain]/use[Domain][Feature].ts |
Use const tCommon = useTranslation('common') for reusable strings:
| Key | Values |
|---|---|
generalActions.* | save, cancel, delete, edit, add, update, archive, retry, search, confirm, restore, back, continue, apply, clear, goBack, share, print |
generalStatuses.* | active, archived, draft, sent, sending, open, created, creating, ready, rejected, updated, ongoing, all, loading |
boolean.* | yes, no |
dateAndTime.* | date, time, hour, startDate, endDate, years_one/other, months_one/other, days_one/other |
dataTable.columns.* | id, date, name, email, phone, status, actions, firstName, lastName, client, veterinarian, clinic |
dataTable.emptyState.* | header, description, descriptionNoMatches, buttonClearFilters |
generalFormFields.* | email, phone, tags, remarks, reasonType, reason, veterinarian, department |
enums.* | invoiceStatus, invoicePaymentStatus, invoiceType, paymentMethod, patientSex, consultationTypes, consultationStatus |
Example usage:
const tCommon = useTranslation('common')
tCommon('generalActions.save') // "Save"
tCommon('generalActions.cancel') // "Cancel"
tCommon('boolean.yes') // "Yes"
tCommon('dataTable.columns.name') // "Name"