codi-layer
codi-layer is a Nuxt layer consumed by all four frontend apps. It provides shared composables, plugins, types, and base components so they don't need to be duplicated.
How It's Used
Each consuming app extends the layer in its nuxt.config.ts:
// customer-booki-web-app/nuxt.config.ts
export default defineNuxtConfig({
extends: ["@codisolutions/codi-layer"], // published npm package
// or: extends: ['../codi-layer'] // local path when iterating
});
What It Provides
Composables (auto-imported)
| Composable | Description |
|---|---|
useAddress() | Address lookup and management helpers |
useAttachments() | File attachment upload and management |
useAuth() | Login, logout, getCurrentUser, token + currentUser state |
useBooking() | All booking API calls + dialog/form state factories |
useBookingOwner() | Owner-side booking management and status transitions |
useBusinessHours() | Business hours configuration API calls |
useContact() | Contact form submission helpers |
useDefaultRoute() | Resolves the default redirect route after login per app |
useFaq() | FAQ CRUD API calls |
useFormHandler() | Validation rules + handleApiAction wrapper |
useMayaPayment() | Maya payment gateway checkout and status polling |
useNotificationDrawer() | Notification drawer open/close state + unread count |
useOrganization() | Organization API calls |
usePackage() | Service/package API calls |
usePage() | Pagination state (page, pages, items, search) |
usePayment() | Payment API calls |
useRealtime() | Real-time event subscription helpers (wraps Socket.IO) |
useSocket() | Reactive Socket.IO connection state |
useSubscription() | Subscription plan management + Maya checkout integration |
useSubscriptionBillingSettings() | Billing settings fetch and update |
useTenant() | Subdomain slug extraction into global state |
useUsers() | User listing, invitation, and role management |
useUtils() | alertRef and misc helpers |
Plugins (auto-loaded)
| Plugin | Effect |
|---|---|
api.ts | Provides $api — typed $fetch with auth + tenant + branch headers and 401 redirect |
auth.client.ts | Bootstraps currentUser from ${cookiePrefix}accessToken cookie on app load |
socket.client.ts | Provides $socket with room join/leave helpers |
phosphor-icons.ts | Registers 16 Phosphor icon components globally |
aos.client.ts | Initializes AOS (Animate on Scroll) with standard settings |
google-identity.client.ts | Ensures Google Identity Services script is loaded on the client |
Types (auto-imported)
All types live in codi-layer/app/types/ as .d.ts declaration files. There is no barrel export (index.ts) — Nuxt's auto-import picks them all up automatically in every consuming app.
| File | Key types |
|---|---|
address.d.ts | TAddress, TAddressForm |
auth.d.ts | TRegister, TRegisterOwner, TLogin |
booking.d.ts | TBooking, TBookingGuest, TBookingId, TReasonEvent |
branch.d.ts | TBranch, TBranchForm |
branch-management.d.ts | TBranchInvitation, TBranchMember |
business-hours.d.ts | TBusinessHours, TBusinessHoursDay |
contact.d.ts | TContact, TContactForm |
invitation.d.ts | TInvitation, TInvitationStatus |
local.d.ts | TStandardResponse, TMenuItem, TApiActionOptions |
notification.d.ts | TNotification, TNotificationPayload |
package.d.ts | TPackage, TPackageForm |
payment.d.ts | TPayment, TPaymentStatus |
socket.d.ts | TSocketRoom, TSocketPayload |
subscription.d.ts | TSubscription, TSubscriptionPlan |
subscription-billing.d.ts | TBillingSettings, TBillingCycle |
user.d.ts | TUser, TCustomer |
// All available without import in any consuming app:
const user = ref<TUser | null>(null);
const booking = ref<TBooking | null>(null);
const options: TApiActionOptions = { successMessage: "Done!" };
runtimeConfig Shape
codi-layer/nuxt.config.ts defines the public runtime config shape that all apps share:
runtimeConfig: {
public: {
cookiePrefix: '', // per-app: 'customer_', 'owner_', 'admin_', 'cms_'
cookieConfig: {
domain: undefined, // production: '.booki.com'; dev: undefined
secure: false, // true in production
maxAge: 30 * 24 * 60 * 60, // 30 days
},
googleClientId: '', // NUXT_PUBLIC_GOOGLE_CLIENT_ID
apiUrl: 'http://localhost:4001',
socketUrl: 'http://localhost:4001',
basePlanPrice: '399',
APP_CMS_BOOKI_WEB_APP: 'http://localhost:3000',
APP_OWNER_BOOKI_WEB_APP: 'http://localhost:3001',
APP_CUSTOMER_BOOKI_WEB_APP: 'http://localhost:3002',
}
}
cookiePrefix is the key field: it scopes cookie names per app so sessions don't collide when running multiple apps on the same localhost (e.g. customer_accessToken vs owner_accessToken). Each consuming app sets this via NUXT_PUBLIC_COOKIE_PREFIX in its .env.
Local Development Linking
When iterating on codi-layer while running a consuming app:
# 1. In codi-layer/ — build in watch mode
yarn dev
# 2. In the consuming app — use local path in extends
# nuxt.config.ts: extends: ['../codi-layer']
# 3. Run dev server
yarn dev
See codi-layer/DEPENDENCY_LINKING.md for details on symlink vs path-based approaches.
Adding to codi-layer
When adding a new shared composable or component to codi-layer:
- Add the file to the appropriate
app/composables/orapp/components/directory. - Nuxt auto-imports handle the rest — no barrel exports needed.
- If it's a new plugin, it auto-loads in consuming apps.
- If it introduces new types, add them to
app/types/with a matching export inapp/types/index.ts. - Test it in one consuming app before marking as stable.
