danwel - Implementation Plan

Phased implementation approach prioritizing feature parity with the prototype on a modern, secure foundation.

---

Table of Contents



1. [MVP Definition](#mvp-definition)
2. [Implementation Phases](#implementation-phases)
3. [Phase Dependencies](#phase-dependencies)
4. [Testing Approach](#testing-approach)
5. [Deployment Strategy](#deployment-strategy)
6. [Prototype Reference](#prototype-reference)

---

MVP Definition



Goal


Rebuild the current prototype with a **clean, modern, secure foundation** that is multi-tenancy ready but initially single-user.

MVP Scope (Phases 1-4)


| Include | Exclude (Later) |
|---------|-----------------|
| Laravel 11 foundation | Team invitations |
| Single org + single user | Organization switching |
| Multi-tenancy *structure* (ready for later) | Multiple users per org |
| Google Calendar integration | Office 365 integration |
| Moneybird integration | Harvest integration |
| Calendar UI with drag-drop | Mobile/tablet PWA |
| User preferences (timezone, work hours) | Reports & analytics |
| Secure encrypted token storage | Audit logging UI |

MVP = Feature Parity with Prototype


When MVP is complete, you should be able to:
1. Register/login as a user
2. Connect Google Calendar (OAuth)
3. Connect Moneybird (OAuth)
4. See weekly calendar with time blocks
5. Create/edit/delete time blocks (drag-drop)
6. Time blocks sync to Google Calendar
7. Time blocks create Moneybird time entries
8. Set timezone, work hours, work days

---

Implementation Phases



Phase 1: Foundation (MVP) ✅ COMPLETED


**Goal:** Laravel app with auth, database, multi-tenancy structure

  • • [x] Fresh Laravel 11 installation

  • • [x] Database migrations:

  • - [x] users (with preferences: timezone, work_days, work_hours)
    - [x] organizations
    - [x] organization_user pivot (with role)
    - [x] integrations
    - [x] calendars
    - [x] clients
    - [x] projects
    - [x] time_blocks
  • • [x] TenantContext service

  • • [x] BelongsToOrganization trait

  • • [x] SetTenantContext middleware

  • • [x] User authentication (Laravel Fortify)

  • • [x] Auto-create organization on registration

  • • [x] Full role system (owner, admin, member, viewer)
  • **Status:** ✅ Complete - User can register, login, and has an organization created automatically.

    **Tests:**
  • • [ ] User registration creates organization

  • • [ ] User is set as owner of their organization

  • • [ ] TenantContext correctly scopes queries
  • ---

    Phase 2: Integration Framework (MVP) ✅ COMPLETED


    **Goal:** Secure OAuth infrastructure for external services

  • • [x] CalendarProviderInterface

  • • [x] InvoicingProviderInterface

  • • [x] ProjectProviderInterface (added for GitHub)

  • • [x] IntegrationManager service

  • • [x] Integration model with encrypted tokens

  • • [x] Calendar model (for multi-calendar support)

  • • [x] Client model (synced from Moneybird)

  • • [x] Project model (synced from Moneybird)

  • • [x] Config-based provider registration

  • • [x] Token refresh middleware/job
  • **Status:** ✅ Complete - Framework supports multiple provider types with secure token management.

    **Tests:**
  • • [ ] Tokens are encrypted in database

  • • [ ] Token refresh works correctly

  • • [ ] Integration scoped to organization
  • ---

    Phase 3: Google Calendar + Moneybird (MVP) ✅ COMPLETED


    **Goal:** Working integrations matching prototype functionality

    **Google Calendar:** ✅
  • • [x] GoogleCalendarProvider implementation

  • • [x] OAuth connect flow

  • • [x] OAuth callback handler

  • • [x] Token refresh

  • • [x] Fetch user timezone on connect

  • • [x] Calendar discovery (list available calendars)

  • • [x] Select calendars to sync

  • • [x] Fetch events for date range

  • • [x] Create event with extendedProperties

  • • [x] Update event

  • • [x] Delete event

  • • [x] Disconnect flow


  • **Moneybird:** ✅
  • • [x] MoneybirdProvider implementation

  • • [x] OAuth connect flow

  • • [x] OAuth callback handler

  • • [x] Token refresh

  • • [x] Fetch administration ID on connect

  • • [x] Fetch Moneybird user ID (required for time entries)

  • • [x] Sync contacts → clients table

  • • [x] Sync projects → projects table

  • • [x] Create contact

  • • [x] Create project

  • • [x] Create time entry

  • • [x] Update time entry

  • • [x] Delete time entry

  • • [x] Disconnect flow
  • **Status:** ✅ Complete - Both services fully functional with comprehensive CRUD operations.

    **Tests:**
  • • [ ] OAuth flow completes successfully (mock external APIs)

  • • [ ] Events sync to Google Calendar

  • • [ ] Time entries sync to Moneybird

  • • [ ] Token refresh on expiry
  • ---

    Phase 4: Time Blocks + Calendar UI (MVP) ✅ COMPLETED


    **Goal:** Full calendar interface with drag-drop, matching prototype

    **Backend:** ✅
  • • [x] TimeBlock model + service

  • • [x] TimeBlock API endpoints:

  • - [x] GET /api/time-blocks (with date range)
    - [x] POST /api/time-blocks
    - [x] PUT /api/time-blocks/{id}
    - [x] DELETE /api/time-blocks/{id}
  • • [x] Sync to Google Calendar on create/update/delete

  • • [x] Sync to Moneybird on create/update/delete

  • • [x] Store external IDs (calendar_event_id, time_entry_id)

  • • [x] Sync status tracking (pending, synced, error)

  • • [x] Background job for sync

  • • [x] Error handling + retry logic


  • **Frontend:** ✅
  • • [x] App layout (nav, user menu)

  • • [x] Settings page:

  • - [x] Connect/disconnect Google Calendar
    - [x] Connect/disconnect Moneybird
    - [x] Select calendars to sync
    - [x] Set timezone
    - [x] Set work hours (start/end)
    - [x] Set work days
  • • [x] Calendar view:

  • - [x] Weekly grid (respects user work hours/days)
    - [x] Horizontal scroll between days
    - [x] Display time blocks
    - [x] Display external calendar events (read-only, different color)
    - [x] Drag to create new block
    - [x] Drag to move block
    - [x] Resize to change duration
    - [x] Click to edit (modal)
    - [x] Delete block
    - [x] Assign client/project to blocks
    - [x] Assign client/project to external events (metadata only)
    - [x] Week navigation (prev/next/today)
    - [x] Week picker
    - [x] Summary row (hours per day, total week)
    - [x] Sync status indicators
  • • [x] Client/project dropdowns (from Moneybird data)

  • • [x] Create client inline

  • • [x] Create project inline
  • **Status:** ✅ Complete - Full feature parity achieved with enhanced functionality beyond original prototype.

    **Tests:**
  • • [ ] Time block CRUD via API

  • • [ ] Sync triggers on create/update/delete

  • • [ ] External events display correctly

  • • [ ] Summary calculation correct
  • ---

    Phase 5: Polish & Hardening (Post-MVP)


    **Goal:** Production-ready quality

  • • [ ] Input validation on all endpoints

  • • [ ] Rate limiting

  • • [ ] Error pages (404, 500, etc.)

  • • [ ] Loading states in UI

  • • [ ] Optimistic UI updates

  • • [ ] Proper error messages to user

  • • [ ] Sync retry with exponential backoff

  • • [ ] Handle API failures gracefully


  • **Tests:**
  • • [ ] Validation rejects bad input

  • • [ ] Rate limiting works

  • • [ ] Sync retries on failure
  • ---

    Phase 6: Team Features (Future)


    **Goal:** Multi-user organizations

  • • [ ] Invitation system

  • • [ ] Accept invitation flow

  • • [ ] Team member list

  • • [ ] Role management (admin, member, viewer)

  • • [ ] Role-based policies

  • • [ ] Organization switching

  • • [ ] View team members' calendars
  • ---

    Phase 7: Advanced Features (Future)


    **Goal:** Extended functionality

  • • [ ] Office 365 calendar integration

  • • [ ] Harvest integration

  • • [ ] Recurring time blocks

  • • [ ] Reports & analytics

  • • [ ] Mobile/tablet PWA

  • • [ ] Subdomain per organization

  • • [ ] Audit logging UI
  • ---

    Phase Dependencies



    Phase 1: Foundation


    Phase 2: Integration Framework


    Phase 3: Google Calendar + Moneybird ─────┐
    │ │
    ▼ │
    Phase 4: Time Blocks + Calendar UI ◄──────┘


    Phase 5: Polish (Post-MVP)


    Phase 6: Team Features (Future)


    Phase 7: Advanced Features (Future)

    **Critical Path:** 1 → 2 → 3 → 4

    **Can parallelize within Phase 3:**
  • • Google Calendar provider

  • • Moneybird provider

  • (Both depend on Phase 2 framework, but not on each other)

    **Can parallelize within Phase 4:**
  • • Backend API

  • • Frontend UI

  • (Frontend can use mock data while backend is built)

    ---

    Testing Approach



    Test As You Build


    Write tests during each phase, not at the end.

    | Phase | Test Focus |
    |-------|------------|
    | Phase 1 | Auth, organization creation, tenant scoping |
    | Phase 2 | Token encryption, integration model |
    | Phase 3 | OAuth flows (mocked), API calls (mocked) |
    | Phase 4 | Time block CRUD, sync triggers |

    Test Types



    **Unit Tests** - Test services and models in isolation:
    tests/Unit/
    ├── Services/
    │ ├── TenantContextTest.php
    │ └── IntegrationManagerTest.php
    └── Models/
    └── TimeBlockTest.php


    **Feature Tests** - Test full request/response cycles:
    tests/Feature/
    ├── Auth/
    │ └── RegistrationTest.php
    ├── Integrations/
    │ ├── GoogleCalendarTest.php
    │ └── MoneybirdTest.php
    ├── TimeBlocks/
    │ ├── CreateTimeBlockTest.php
    │ ├── UpdateTimeBlockTest.php
    │ └── SyncTimeBlockTest.php
    └── MultiTenancy/
    └── OrganizationIsolationTest.php


    Critical Test Cases (MVP)



    1. **Tenant isolation** - User cannot access other org's data
    2. **Token security** - Tokens encrypted at rest
    3. **Sync reliability** - Time blocks sync to external services
    4. **Token refresh** - Expired tokens refresh automatically

    Mocking External APIs



    Don't hit real Google/Moneybird APIs in tests:
    // Mock Google Calendar API responses
    Http::fake([
    'googleapis.com/*' => Http::response([...], 200),
    ]);

    // Mock Moneybird API responses
    Http::fake([
    'moneybird.com/*' => Http::response([...], 200),
    ]);

    ---

    Deployment Strategy



    SpinupWP Setup



    ``env

    Application


    APP_NAME=danwel
    APP_ENV=production
    APP_URL=https://danwel.yourdomain.com

    Database


    DB_CONNECTION=mysql
    DB_DATABASE=danwel
    DB_USERNAME=danwel_user
    DB_PASSWORD=SECURE_PASSWORD

    Cache & Queue


    CACHE_DRIVER=redis
    SESSION_DRIVER=redis
    QUEUE_CONNECTION=redis

    Integrations


    GOOGLE_CLIENT_ID=xxx
    GOOGLE_CLIENT_SECRET=xxx
    GOOGLE_REDIRECT_URI=https://danwel.yourdomain.com/integrations/google_calendar/callback
    MONEYBIRD_CLIENT_ID=xxx
    MONEYBIRD_CLIENT_SECRET=xxx
    MONEYBIRD_REDIRECT_URI=https://danwel.yourdomain.com/integrations/moneybird/callback

    Deployment Script


    bash
    #!/bin/bash
    cd $RELEASE_PATH

    composer install --no-dev --optimize-autoloader
    npm ci && npm run build

    php artisan config:cache
    php artisan route:cache
    php artisan view:cache
    php artisan migrate --force
    php artisan queue:restart

    Queue Workers



    Required for background sync operations:
    bash

    Supervisor config for queue worker


    [program:danwel-worker]
    process_name=%(program_name)s_%(process_num)02d
    command=php /path/to/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
    autostart=true
    autorestart=true
    stopasgroup=true
    killasgroup=true
    numprocs=2
    `

    Scheduled Tasks



    // app/Console/Kernel.php
    $schedule->command('integrations:refresh-tokens')->hourly();
    $schedule->command('integrations:sync-calendars')->everyFifteenMinutes();
    $schedule->command('integrations:retry-failed')->everyFiveMinutes();

    ---

    Prototype Reference

    The original prototype is preserved in initial_prototype/ for reference during the Laravel rebuild.

    Prototype File Summary



    | File | Lines | Key Functionality |
    |------|-------|-------------------|
    |
    initial_prototype/config.php | 44 | OAuth credentials, color constants |
    |
    initial_prototype/index.php | 182 | Settings page, connection status UI |
    |
    initial_prototype/callback.php | ~90 | Google OAuth code exchange, timezone fetch |
    |
    initial_prototype/moneybird-callback.php | ~87 | Moneybird OAuth, administration fetch |
    |
    initial_prototype/api.php | 758 | Full REST API |
    |
    initial_prototype/calendar.php | 1,434 | Calendar UI + JavaScript |

    Key Code to Port



    **From
    initial_prototype/callback.php:**
  • • Token exchange with Google

  • • Fetching user timezone on connect


  • **From
    initial_prototype/moneybird-callback.php:**
  • • Token exchange with Moneybird

  • • Fetching administration ID

  • • Fetching Moneybird user ID


  • **From
    initial_prototype/api.php:**
  • • Time entry CRUD to Moneybird

  • • Event CRUD to Google Calendar

  • • Extended properties for linking data


  • **From
    initial_prototype/calendar.php`:**
  • • interact.js drag-drop configuration

  • • Week picker logic

  • • Summary calculation

  • • Color mapping (Google colorId → hex)


  • Prototype Limitations → Laravel Solutions



    | Limitation | Laravel Solution |
    |------------|------------------|
    | Single-user (no auth) | Laravel Breeze + Sanctum |
    | File-based tokens | Encrypted database storage |
    | No database | MySQL with proper schema |
    | Google Calendar as source of truth | Local DB as source of truth |
    | Hardcoded work hours (8am-6pm) | User preferences |
    | Hardcoded work days (Mon-Sun) | User preferences |
    | No timezone customization | User preferences |
    | No multiple calendar support | Calendar model + multi-select |

    ---

    MVP Checklist Summary



    **Phase 1: Foundation**
  • • [ ] Laravel 11 + Breeze auth

  • • [ ] All database tables created

  • • [ ] User registration creates org

  • • [ ] Tenant scoping works


  • **Phase 2: Integration Framework**
  • • [ ] Provider interfaces defined

  • • [ ] Encrypted token storage

  • • [ ] Token refresh mechanism


  • **Phase 3: Integrations**
  • • [ ] Google Calendar OAuth works

  • • [ ] Google Calendar CRUD works

  • • [ ] Moneybird OAuth works

  • • [ ] Moneybird time entries work

  • • [ ] Clients/projects sync from Moneybird


  • **Phase 4: UI**
  • • [ ] Settings page (integrations, preferences)

  • • [ ] Calendar grid with time blocks

  • • [ ] Drag-drop create/move/resize

  • • [ ] Week navigation

  • • [ ] Summary row

  • • [ ] Sync to external services
  • **MVP Complete** = All above checked ✅

    ---

    Post-MVP Development Status

    **MVP was completed and the system has been significantly enhanced beyond the original scope:**

    Additional Features Implemented


  • • **Task/Entry Management System** - Full project management with entries, comments, labels

  • • **Advanced Authentication** - OAuth (Google, GitHub, Apple), WebAuthn, 2FA, magic links

  • • **GitHub Integration** - Repository linking, issue sync, webhooks

  • • **Team Management** - Full invitation system with roles and permissions

  • • **Platform Administration** - Admin dashboard, user impersonation, audit logging

  • • **Multi-language Support** - Comprehensive EN/NL localization

  • • **Demo Mode** - Guided demo experience with usage restrictions

  • • **Mobile App Support** - Token-based authentication for external apps

  • • **Billing System** - VAT validation and billing address management

  • • **Advanced UI Features** - Favorites, enhanced preferences, statistics dashboard


  • Current Status: Production Ready


    The system has evolved from a simple MVP into a comprehensive project management and time tracking platform that's currently in production use.