- New Translations + TranslationTexts NocoDB tables (auto-created on restart)
- Full CRUD: list, create, update, delete, bulk-delete translations
- Translation texts per language (add/edit/delete inline)
- Review flow: submit-review generates public token link
- Public review page: shows source + all translations, approve/reject/revision
- Email notifications to approvers (registered users)
- Sidebar nav under Marketing category
- Bilingual i18n (80+ keys in en.json and ar.json)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds preferred_language field to Users, language picker (EN/AR) in
create/edit user form, persists to NocoDB, and passes it to the
welcome notification so new users receive emails in their language.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Notifications (fire-and-forget, non-blocking) for: review submitted,
approved/rejected/revision requested, task assigned/completed, issue
assigned/status changed, campaign created, user invited. Emails render
in user's preferred language (EN/AR) with RTL support. Adds
preferred_language to Users, syncs from frontend language toggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Removed h1 titles from Settings and Brands (already in Header)
- Server injects og:title, og:description, og:image meta tags for
/review-post/:token URLs so WhatsApp/Slack show proper previews
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show button only when post has no approval token. Once a link exists,
only the link is shown. Server preserves status for non-draft posts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reject requires feedback on both client and server (400 if empty)
- PublicPostReview uses post-specific i18n keys instead of artefact ones
- Team list always includes superadmins/managers for non-superadmin users
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Token-based public review page at /review-post/:token
- Submit for Review button generates shareable link
- External reviewers can approve/reject with comments
- Approval gate prevents skipping review (superadmin override)
- i18n keys for review flow in en + ar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add approval process to posts (approver multi-select, rejected status column)
- Reorganize PostDetailPanel into Content, Scheduling, Approval sections
- Fix save button visibility: move to fixed footer via SlidePanel footer prop
- Change date picker from datetime-local to date-only
- Complete Arabic translations across all panels (Header, Issues, Artefacts)
- Fix artefact versioning to start empty (copyFromPrevious defaults to false)
- Separate media uploads by type (image, audio, video) in PostDetailPanel
- Fix team membership save when editing own profile as superadmin
- Server: add approver_ids column to Posts, enrich GET/POST/PATCH responses
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NocoDB list endpoint doesn't always return all fields (e.g.
password_hash). Use list() to find by email/token, then get()
to fetch the full record with all fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migrate auth credentials from SQLite (auth.db) to NocoDB Users table
with one-time migration function (auth.db → auth.db.bak)
- Add email-based password reset via Cloudron SMTP (nodemailer)
- Add GET /api/health endpoint for monitoring
- Add startup env var validation with clear error messages
- Strip sensitive fields (password_hash, reset_token) from all API responses
- Add ForgotPassword + ResetPassword pages with i18n (en/ar)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Multi-select bulk delete in all 5 list views (Artefacts, Posts, Tasks,
Issues, Assets) with cascade deletes and confirmation modals
- Team-based issue dispatch: team picker on public issue form, team filter
on Issues page, copy public link from Team page and Issues header,
team assignment in IssueDetailPanel
- Month/Week toggle on PostCalendar and TaskCalendarView
- Month/Week/Day zoom on project and campaign timelines (InteractiveTimeline)
and ProjectDetail GanttView, with Month as default
- Custom timeline bar colors: clickable color dot with 12-color palette
popover on project, campaign, and task timeline bars
- Artefacts default view changed to list
- BulkSelectBar reusable component
- i18n keys for all new features (en + ar)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove team_role and brands from profile completion wizard
- Lock team_role and brands fields when user edits own profile
- Remove team_role and brands from PATCH /users/me/profile endpoint
- Profile completeness now checks name instead of team_role
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove team_role filter from GET /api/users/team — all users now
appear in the team view
- POST /api/users now accepts team_role, brands, phone, modules
- PATCH /api/users/:id now accepts team_role, phone, brands, modules
- Users without team_role display their system role as fallback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tables like Users, Brands, Campaigns, Projects, etc. are now created
automatically by ensureRequiredTables() if they don't exist, removing
the need to run setup-tables.js manually on fresh deployments.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no users exist in the database, the login page shows a setup
form to create the initial superadmin account. The /api/setup
endpoint is locked once the first user is created.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Dashboard stat card: show "Budget Remaining" instead of "Budget Spent"
with correct remaining value accounting for campaign allocations
- Add expense system: budget entries now have income/expense type with
server-side split, per-campaign and per-project expense tracking,
colored amounts, type filters, and summary bar in Budgets page
- Add configurable currency in Settings (SAR default, supports 10
currencies) replacing all hardcoded SAR references across the app
- Replace PiggyBank icon with Landmark (culturally appropriate for KSA)
- Visual upgrade: mesh background, gradient text, premium stat cards with
accent bars, section-card containers, sidebar active glow
- UX polish: consistent text-2xl headers, skeleton loaders for Finance
and Budgets pages
- Finance page: expenses column in campaign/project breakdown tables,
ROI accounts for expenses, expense stat card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add campaign_assignments table for user-to-campaign mapping
- Superadmin/managers can assign users to campaigns; visibility filtered by assignment/ownership
- Managers can only manage (tracks, assignments) on campaigns they created
- Budget controlled by superadmin only, with proper modal UI for editing
- Ownership-based editing for campaigns, projects, comments (creators can edit their own)
- Role-scoped dashboard and finance data (managers see only their campaigns' data)
- Manager's budget derived from sum of their campaign budgets set by superadmin
- Hide UI features users cannot use (principle of least privilege across all pages)
- Fix profile completion prompt persisting after saving (login response now includes profileComplete)
- Add post detail modal in campaign detail with thumbnails, publication links, and metadata
- Add comment inline editing for comment authors
- Move financial summary cards below filters on Campaigns page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Features:
- Full RBAC with 3 roles (superadmin/manager/contributor)
- Ownership tracking on posts, tasks, campaigns, projects
- Task system: assign to anyone, filter combobox, visibility scoping
- Team members merged into users table (single source of truth)
- Post thumbnails on kanban cards from attachments
- Publication link validation before publishing
- Interactive onboarding tutorial with Settings restart
- Full Arabic/English i18n with RTL layout support
- Language toggle in sidebar, IBM Plex Sans Arabic font
- Brand-based visibility filtering for non-superadmins
- Manager can only create contributors
- Profile completion flow for new users
- Cookie-based sessions (express-session + SQLite)