db: activities.assigneeId column (string, optional)
activity-actions: assigneeId saved on create (default: self), cleared on update
validation: assigneeId added to activitySchema
schema: assigneeId field on Activity type
activity-form-sheet: Atanan Kişi dropdown for owner/admin with member list
activity-team-view: new component — activities grouped by assignee,
completion/edit/delete actions, overdue indicator, member avatars
activities-client: Ekip tab (owner/admin only), members + currentUserId props
activities page: fetches team memberships + user details, passes to client
activity-email-actions: filter by assigneeId ?? createdBy for both me/team modes
- activity-email-actions: sendDailySummaryAction — filters today's
activities by dueDate, sends personalized email via Appwrite Messaging
- 'me': current user's activities only
- 'team' (owner/admin): each member gets their own activities separately
- send-summary-dialog: dialog with me/team radio (owner/admin only sees
team option), inline error + toast on success
- activities-client: 'Günlük Özet' button in header, role prop added
- activities page: passes ctx.role to client
- middleware: remove auth-path→/dashboard redirect; stale session cookies
caused dashboard→onboarding→sign-in→dashboard infinite loop
- dashboard layout: check getCurrentUser first, redirect to /sign-in
directly instead of going through /onboarding
- getActiveContext: use admin client (users.listMemberships) for tenant
resolution instead of session-dependent getUserTeams()
- requireTenant: validate membership before trusting stored tenantId;
clear stale cookie and re-resolve if user is not a member
- sunum page: JSON.parse/stringify property rows before passing to
Client Component (Appwrite SDK objects have non-plain prototypes)
- getActiveContext now verifies team still exists (teams.get) before
trusting the cookie/prefs tenantId, preventing stale E Ofis cookie
from causing an onboarding redirect loop
- Resolved tenantId from getUserTeams() is now persisted to cookie so
subsequent requests skip the resolution path
- Added catch+log on presentations data fetch to surface the actual
error in server logs
- ensureSettings() creates a minimal settings row if one is missing for
a team the user is already a member of, instead of returning null and
letting the onboarding redirect fire
- resolveFirstValidTenantId() falls back to any membership when no team
has settings yet, so new registrations without a completed onboarding
still land on the correct tenant
- teams.get() is now fetched alongside listMemberships in a single
Promise.all so the team name is available for the fallback row
- saveThemePrefsAction: account.updatePrefs ile mevcut prefs'i merge eder
- Dashboard layout'ta account.getPrefs ile prefs server-side yüklenir
- PrefsInitializer: mount'ta dark/light, renk teması, radius, sidebar
config'ini Appwrite'dan gelen initialPrefs ile uygular
- ThemeCustomizer: renk teması / tweakcn / radius / sidebar değişikliği
anında Appwrite'a kaydedilir; dark/light toggle useEffect ile izlenir
- Sayfa yenileme ve farklı cihazda giriş sonrasında ayarlar korunur
Empty string sent to Appwrite datetime column was being interpreted as creation
timestamp, making every no-expiry sunum immediately expired. Fix:
- Only include expiresAt in payload when user actually set a date
- Convert date-only string (YYYY-MM-DD) to YYYY-MM-DDT23:59:59.000Z so the
sunum stays valid for the entire chosen day across all time zones
- Strip empty customerId/notes to avoid empty-string writes
matchPropertyToSearches now:
- scores every search (listing type mismatch = 0 score)
- score >= 20: create or update match
- score < 20 AND existing match: delete stale record
Prevents outdated match records after criteria/weight updates.
- Server actions: property/customer/search/presentation/activity/investor CRUD
- Matching engine: matchPropertyToSearches + syncMatchesForSearch on search save
- UI: form sheets + table clients for all modules
- Public /sunum/[token] page (no auth) with property card grid + expiry check
- All pages force-dynamic for auth guard compatibility