- Layout split: (dashboard)/layout.tsx is now async server component that
fetches active context and passes user/company to (dashboard)/dashboard-shell.tsx
(client). Redirects to /onboarding if no tenant.
- AppSidebar:
* Header shows 'İşletmem' + the active company name (companyName from
tenant_settings), instead of mock 'ShadcnStore / Admin Dashboard'.
* Nav rebuilt for our modules in Turkish: Genel bakış, Müşteriler,
Hizmetler, Yazılımlarımız, Takvim, Görevler, Gelir/Gider, Faturalar,
Çalışma alanı (with submenu), Profil, Plan.
* Removed SidebarNotification (template promo widget).
* Accepts user/company props (typed via ShellUser/ShellCompany).
- NavUser:
* Real user name + email, no more 'ShadcnStore / store@example.com'.
* Avatar shows initials from name in primary/10 tinted square.
* Logout wired to signOutAction (server action) via useTransition.
* Menu items localized (Profil, Plan & Faturalama, Bildirimler, Çıkış yap).
- SiteHeader:
* Removed Blocks / Landing / GitHub external links (template demo links).
* Shows company name with Building2 icon between sidebar trigger and
search trigger.
* Search trigger moved to right side next to ModeToggle.
- Dropped UpgradeToProButton from the shell (template promo).
- Deleted dead-code src/components/layouts/base-layout.tsx (unused alt
layout that wasn't compatible with the new AppSidebar props).
- /dashboard now a server component:
* fetches active user + active tenant settings via getActiveContext()
* redirects to /onboarding if user has no tenant yet
* header shows companyName + 'Hoş geldiniz, {firstName}' + Turkish description
- Body reuses dashboard-2 components (Metrics/Sales/Revenue/Transactions/
TopProducts/CustomerInsights/QuickActions). Mock data for now; will be
swapped for live Appwrite queries as modules ship.
- New lib/appwrite/active-context.ts: getActiveContext() returns
{ user, tenantId, settings } for any server component / action.
- Made schema.ts SDK-agnostic by replacing Models.Document import with a
local SystemRow type ({ $id, $createdAt, $updatedAt, $permissions, ... }).
Avoids type clashes between appwrite (browser) and node-appwrite (server).
Two fixes triggered by user-reported error 'Invalid document structure:
Unknown attribute createdBy' during onboarding:
1) tenant_settings has no createdBy column by design (one row per tenant,
creator metadata is redundant). Removed createdBy from the row payload.
2) Made the action atomic: if any step after teams.create fails (row write,
prefs, cookie), delete the just-created team using the admin client.
Without this, two failed attempts left two orphan teams; reload then
redirected the user to /dashboard with no tenant_settings, trapping them.
Already cleaned up the two orphan teams via Appwrite MCP.
- /onboarding page (server component): redirects to /sign-in if not authed,
to /dashboard if user already has a team. Otherwise renders form.
- createWorkspaceAction:
* teams.create (user becomes owner via session SDK)
* tablesDB.createRow on tenant_settings (admin SDK) with team-scoped permissions:
Permission.read(Role.team(id)), update(owner|admin), delete(owner)
* account.updatePrefs({ activeTenant }) — persisted source of truth
* isletmem-tenant cookie for fast access
* redirect to /dashboard
- setActiveTenantAction stub for future workspace switcher
- lib/appwrite/tenant.ts: getUserTeams, getActiveTenantId helpers (server-only)
- tenant-types.ts holds WorkspaceState + ACTIVE_TENANT_COOKIE (no 'use server')
node-appwrite 24.x and appwrite 25.x target Appwrite server 1.9.1.
Our self-hosted server runs 1.9.0, which produced an SDK-version
mismatch warning on every API call.
Pinned:
node-appwrite: ^23.1.0 (was ^24.0.0)
appwrite: ^24.2.0 (was ^25.0.0)
v23/v24 keep both positional and params-object overloads, so existing
auth-actions.ts calls (createEmailPasswordSession, createRecovery,
account.create) compile and run unchanged. When we upgrade Appwrite to
1.9.1 we can bump the SDKs back.
Server-action files ('use server') can only export async functions.
Exporting initialAuthState (object) caused:
'A use server file can only export async functions, found object'
when sign-up form was submitted.
Moved AuthState type and initialAuthState const to lib/appwrite/auth-types.ts.
Updated 3 form components to import the const from the new location.
- Server actions in lib/appwrite/auth-actions.ts:
signInAction, signUpAction, forgotPasswordAction, signOutAction
All use node-appwrite admin client; session secret stored as httpOnly
cookie (isletmem-session). Errors localized to Turkish.
- Redesigned /sign-in and /sign-up using sign-in-3 split-card layout,
branded as 'İşletmem' with gradient brand panel (no external image).
Removed social login buttons (email/password only for now).
- /forgot-password localized; success state shows email-sent confirmation.
- Auth pages redirect to /dashboard if user already has a session.
- middleware.ts:
* Protects /dashboard, /onboarding, /settings — redirects to /sign-in?redirect=...
* Auth pages redirect logged-in users to /dashboard
* Keeps legacy /login and /register redirects