Design documentation

Student Time Planner — Project folio

This folio documents how Student Time Planner was designed and built — an AI-assisted weekly study planner that helps students know what to do and when, using Next.js, TypeScript, MongoDB, and Gemini.

Problem definition

Senior secondary students juggle school, homework, sport, and social commitments in the same week. A major reason work does not get done is not a lack of intention — it is the friction of starting: deciding what to do next, when it fits, and how to recover when a plan slips. Paper planners and generic calendar apps still leave that planning burden on the student. They require repetitive data entry, do not understand fixed school blocks versus movable study, and rarely help when a task overruns or is missed.

Student Time Planner addresses this need with an AI-assisted week view. Students talk to the planner in plain language (“add an hour of English tonight”) or upload a photo of their printed school timetable so subject blocks appear as fixed, recurring activities. The system treats school and sport as immovable by default, marks overdue incomplete tasks clearly, and validates every AI change before it is written so the calendar stays consistent. The opportunity is a low-friction product that students will actually open — a guide for the week, not another empty grid to fill by hand.

Functional requirements

IDRequirement descriptionPriority
FR1Users can sign in with a one-time email code (or demo account) and sign out; sessions are cookie-based.High
FR2Users see a Monday–Sunday week view with working hours, today highlighted, and a live now-indicator.High
FR3Users can create, edit, complete, delete, and reschedule tasks and activities (tasks only are completable).High
FR4Users can edit the calendar via natural language through the command bar (AI proposes validated operations).High
FR5Users can upload a timetable image, review extracted blocks, and confirm before save.High
FR6Recurring items expand into weekly occurrences; exceptions skip dates without orphan duplicates.High
FR7Split-session tasks render as one logical item across multiple time blocks.Medium
FR8Each user’s items are private; queries are scoped to the authenticated user id.High
FR9Overdue incomplete tasks are visually distinct (orange) with a reschedule path.Medium
FR10Project documentation covers planning, design, algorithms, and automated tests.High

Non-functional requirements

CategoryRequirement
SecuritySigned JWT session cookies; one-time login codes; Zod validation on all writes; no cross-user data access; secrets only in environment config.
PerformanceWeek expansion happens in memory from fetched items; AI apply is all-or-nothing to avoid half-updated calendars; images processed only on upload.
UsabilityWeek-first UI, plain-language command bar, review step for timetable import, consistent accent colour and status colours.
AccessibilitySemantic structure, keyboard-reachable controls where practical, readable type sizes, colour not the only cue for completed vs overdue.
PortabilityRuns on any laptop with Node.js and npm; dependencies declared in package.json.
MaintainabilityTypeScript modules by concern (auth, calendar, AI, db); single Zod source of truth; automated Vitest suite for calendar core.
ReliabilityMalformed AI output is rejected; immovable activities are not shifted by bulk reschedule unless explicitly requested.

Storyboard

The storyboard is a UML activity diagram of the main student journey. Rounded rectangles are actions; diamonds are decisions; filled dots are merge points; the solid circle is the start and the bullseye is the end. Authentication always reaches Load week view (after an email code if needed). From Choose next action the student picks AI (validate then all-or-nothing apply, or clarify and retry), timetable photo (confirm or cancel), UI edit, or change week (reload). Successful AI / photo / UI paths merge, refresh the week, then either continue or sign out.

Open plannerSignedin?NoEnter email codeYesLoad week viewChoose next actionWhichaction?PHOTOAIUINAVUploadtimetable photoTalk viacommand barEdit / completein UIChange weekUserconfirms?YesSave fixedweekly blocksCancelOpsvalid?YesApply batchall-or-nothingNo — clarifyWrite item changeReload weekRefresh week viewKeepusing?YesNo — sign out
Figure 1 — UML activity diagram: student journey with decisions and branches

Financial feasibility

The target users are secondary students who need a planner they can afford. Existing tools (Google Calendar, Notion, study apps) do not combine free school-timetable photo import with validated AI scheduling around immovable school blocks. Student Time Planner is designed to run on a low ongoing cost so the product can stay free for students, or charge a low optional fee that still undercuts typical productivity subscriptions.

Cost itemInitialOngoingNotes
Developer timeSee opportunity cost$0 cashOwn labour
Hosting (Vercel hobby / local)$0$0–$20 / monthLocal run is enough for demos
MongoDB Atlas M0$0$0 / monthFree tier for early users
Resend email$0$0 / monthFree tier for login codes
Google Gemini API$0$10 / monthToken budget for NL + timetable vision
Domain name$23 / year$23 / yearCustom URL for the live product

Funding sources: own unpaid labour for build time; vendor free tiers (Vercel, MongoDB Atlas M0, Resend) for early hosting/auth; personal funds for Gemini tokens and the domain. No external investors or school budget are required for a class demo or a small pilot.

Cash operating cost (steady state): about $10/month for Gemini plus $23/year for the domain → roughly $12/month all-in (domain averaged). Annual cash burn ≈ $143 (12 × $10 + $23).

Opportunity cost: at a bakery wage of $25.50/hour, about 70 hours of design and development equals $1,785 forgone wages. That is the main economic cost of producing the software.

Break-even analysis

Monthly cash burn is treated as $12. If the product stays free for students, break-even in cash terms is already met once free-tier limits hold — the remaining question is whether the builder accepts the $1,785 labour cost as assessment/portfolio investment.

If an optional student subscription is introduced at $3/month (well below typical Notion/AI tool pricing):

Paying usersMonthly revenueVs $12 burnResult
4$12Covers burnCash break-even
20$60+$48Tokens + small buffer
50$150+$138Room for paid DB if needed
200$600+$588Comfortable operating margin

Break-even users = monthly burn ÷ price = 12 ÷ 3 = 4 paying students. That is a realistic pilot size for one school cohort. Commercial alternatives already exist for generic calendars, but not as a free, timetable-photo + validated AI week guide aimed at Australian secondary students — so the opportunity remains financially feasible for the target user and viable to operate at low scale.

Dataflow diagram (DFD)

Level 1 data flow diagram for Student Time Planner. Circles are processes, open-sided rectangles are data stores, closed rectangles are external entities, and labelled curved arrows show data moving between them.

StudentResendGeminiP1AuthP2AI CmdP3TimetableP4Item StoreD1 UsersD2 CodesD3 Itemsemail / codesessionNL requesttimetable photosend codeuser recordstore codeopsweek viewCRUD itemssave blocksimage / draft
Figure 2 — Level 1 data flow diagram

Data dictionary

Each stored field is listed with its type, display format, sizes, purpose, example, and validation rules.

VariableData typeFormat for displaySize in bytesSize for displayDescriptionExampleValidation
userIdStringXX..XX2424Primary key identifying the signed-in user (Mongo ObjectId hex or demo id).demo-userRequired; non-empty
emailStringXX..XX6464Login email for one-time codes.sam@school.eduValid email; stored lower-case
itemIdStringXX..XX2424Primary key for a calendar item.507f1f77bcf86cd799439011Unique; required
typeStringXX..XX88Whether the item is a task or an activity.taskMust be task or activity
titleStringXX..XX20040Display name on the calendar card.English essayLength 1–200
colorString#NNNNNN77Hex colour for the card.#66AA3CRegex ^#[0-9A-Fa-f]{6}$
movableBooleanX1 bit1Whether AI may freely reschedule the item.Ntrue/false; activities default false
segmentStartDate and TimeYYYY-MM-DD HH:mm416Start of a one-off time block (ISO stored).2026-07-22 19:00Valid datetime with offset
segmentEndDate and TimeYYYY-MM-DD HH:mm416End of a one-off time block.2026-07-22 20:00Must be after segmentStart
freqStringXX..XX88Recurrence frequency.weeklydaily or weekly
byWeekdayArray (Integer)N,N,…713Luxon weekdays the series repeats on (1=Mon … 7=Sun).1,2,3,4,5Each value 1–7; weekly needs ≥1
timeStartStringHH:mm55Local start time for a recurring series.08:30Valid HH:mm; before timeEnd
timeEndStringHH:mm55Local end time for a recurring series.15:00Valid HH:mm; after timeStart
intervalIntegerN11Week stride (2 = Week A/B fortnight).2Integer 1–4 if set
exceptionsArray (String)YYYY-MM-DD10 * n10Dates skipped in a recurring series.2026-07-22Each entry valid yyyy-MM-dd
completedBooleanX1 bit1Whether a task is done.YOnly allowed when type = task
loginCodeStringNNNNNN66One-time sign-in code (hashed at rest).482193Exactly 6 digits; short TTL

UML class diagram

User+ String id+ String email+ DateTime createdAtLoginCode+ String email+ String codeHash+ DateTime expiresAtItem+ String id+ String userId+ String type+ String title+ String color+ Boolean movable+ String tzSegment+ DateTime start+ DateTime endRecurrence+ String freq+ Int[] byWeekday+ String timeStart+ String timeEnd+ String startDate+ Int intervalOccurrence+ String key+ String date+ DateTime start+ DateTime end+ String status1*requests1*ownshas 1..*has 0..1expandsTo
Figure 3 — Class diagram (attributes and relationships)

ER diagram

Logical entity–relationship view of the MongoDB collections. Each item belongs to one user; login codes are short-lived auth records.

USERSstring idstring emaildatetime createdAtITEMSstring idstring userIdstring typestring titlestring colorboolean movablestring tzLOGIN_CODESstring emailstring codeHashdatetime expiresAtownshas10..*10..*
Figure 4 — Entity relationship diagram

Research and selection of development approach

Choosing how to organise a multi-week software project matters as much as choosing a framework. Three common approaches taught in software engineering are Waterfall, Agile, and WAgile (a hybrid of Waterfall planning with Agile delivery). This section compares them by project scale and workflow, cites real-world practice, then justifies the approach used for Student Time Planner.

Waterfall

Waterfall sequences requirements → design → implementation → testing → deployment as largely one-way stages. Documentation is front-loaded: the problem, data model, and interfaces are meant to be “finished” before coding begins. Scale-wise, Waterfall historically suits large, contractual programmes where change is expensive and the problem is relatively stable — defence systems, regulated government platforms, and civil-engineering-style software schedules. Workflow-wise, each stage has a gate; testers receive a build late; feedback that contradicts an early requirement is costly because earlier artefacts are treated as locked.

A useful case study is the classic UK government and large enterprise programmes of the 1990s–2000s that adopted Waterfall-like stage gates (and later public inquiries into delayed IT). Those projects were large in team size and budget, with many stakeholders and fixed contracts. The workflow matched procurement: sign off a specification, then build to it. For Student Time Planner, that pattern is a poor fit. The product is small in team size (one developer) but uncertain in behaviour: Gemini may invent item ids, recurrence edge cases appear only when expanding a real week, and timetable photos vary by school. Locking a complete design before those discoveries would waste time rewriting “finished” documents instead of tightening validation code.

Agile

Agile favours working software every short cycle, continuous backlog refinement, and responding to change over comprehensive upfront documentation. Scale-wise it thrives in small-to-medium product teams that can ship, measure, and pivot — typical SaaS startups and product squads. Workflow-wise, stories are sliced vertically (a thin path through UI, API, and data), demos replace stage-gate reviews, and tests grow alongside features.

Industry examples are well known. Spotify’s squad model popularised autonomous teams owning a slice of the product with frequent releases. Many modern web products (from early Dropbox/Slack-style startups to continuous-delivery SaaS firms) use sprint or kanban loops so customer feedback arrives while the design is still malleable. For this planner, Agile’s strengths matched the technical risk: ship auth, then a week view, then AI operations, then timetable import — each slice usable. The weakness is documentary: pure Agile can leave DFDs, algorithms, and requirement tables thin even when the app works. For a Year 12 Software Engineering folio, that weakness matters — markers need evidence of planning and design, not only commits.

WAgile

WAgile deliberately combines both. A short Waterfall-style front end fixes the problem statement, major functional/non-functional requirements, architecture boundaries, and milestones. Delivery then follows Agile sprints that implement and revise features against that spine. Scale-wise, WAgile targets the middle band: projects too complex for “code first, document never,” but too uncertain for a full Waterfall freeze. Workflow-wise it maps to a fixed school delivery window with Gantt milestones (initiation, core build, AI, polish, documentation) while still allowing daily coding loops and retrospective fixes.

Hybrids like this appear in industry whenever regulated or assessed work must meet a deadline yet still absorb discovery — for example product teams inside banks that keep an architecture decision record and release train, or student/industry projects that must submit design packs alongside demos. The comparison on scale is therefore: Waterfall for large stable contracts; Agile for continuous product evolution with light ceremony; WAgile for small teams with a hard deadline and a required design artefact set. Student Time Planner — one developer, feature-rich surface (auth, calendar math, LLM tooling, image import), fixed Term 3 submission — sits squarely in the WAgile band.

Selected approach: WAgile

On scale: one developer, one product, roughly three weeks of intensive build time inside a school term. On workflow: a written spine first (problem, FRs/NFRs, data rules), then short implement–test–adjust loops for each vertical slice. That combination is exactly what WAgile describes, and it is why Waterfall or Agile alone would have been weaker choices for this assessment context.

Upfront, the product overview locked non-negotiable rules: activities immovable by default, tasks only completable, validate before write, Australia/Sydney time, and week-first UX. Those decisions acted as the Waterfall spine so later coding did not reinvent the product concept every day. Delivery then proceeded in vertical Agile slices: MongoDB item documents → week expansion and UI → passwordless auth → Gemini operations pipeline → timetable review → automated tests and this folio. When Gemini returned messy JSON or invented ids, the design adapted by tightening Zod schemas and an all-or-nothing apply step rather than rewriting a frozen Waterfall design pack. When a duration update failed in real use (“Nothing to update on that item”), the response was a small Agile loop: reproduce, extend updateItem, add a regression test, update the folio — without abandoning the overall milestone plan.

In short, Waterfall alone would have delayed learning about AI and recurrence until too late; Agile alone would have under-documented the system for assessment and future maintenance. WAgile provided a documented spine with room to learn — the strongest justification for this project’s scale and workflow.

Project management — Gantt chart

Planned phases with dependencies. Calendar and AI work overlapped; documentation and automated tests concentrated near the end of the build.

Figure 5 — Gantt chart of planned schedule

Critical path: items model → expansion → week UI → AI apply. Auth can proceed in parallel once the data layer exists. Folio and tests depend on a stable domain model so expected outputs can be asserted.

Project diary

DateDescriptionChallenges / milestones
30-06-26Created the Next.js repository (commit 2fac498). Drafted the project overview: week view, AI command bar, timetable photo import, immovable school blocks.Milestone: repository created. Decision: TypeScript + Next.js + MongoDB (teacher-approved stack).
02-07-26Wrote domain rules in the overview (tasks vs activities, validate-before-write, Australia/Sydney). Sketched FR/NFR list for the folio spine.WAgile spine started: problem and constraints locked before deep coding.
05-07-26Chose MongoDB document shape for Item / Segment / Recurrence. Added Zod schemas as the single validation source.Decision: document store fits flexible recurrence, exceptions, and overrides better than a rigid SQL layout for this prototype.
08-07-26Implemented expandWeek / expandItem: weekday series, exceptions, fortnightly interval, split sessions.Challenge: split sessions must share one logical card — solved with shared item id + segment keys.
10-07-26Built week grid UI: day columns, working-hour scaling, now-indicator, complete checkbox, delete, item modal.Milestone: first usable vertical slice (data → visible week).
12-07-26Added passwordless auth: Resend email codes, jose JWT cookie, proxy gate, demo login for offline demos.Challenge: email optional in development — codes logged to console when RESEND_API_KEY unset.
15-07-26Wired Gemini command bar: prompt context, operation schema, apply planner.Challenge: model hallucinating item ids and half-valid batches — introduced full validation before any write.
17-07-26Hardened AI apply: immovable enforcement, all-or-nothing batches, clarification path when ops are empty.Decision: fail closed on bad AI output rather than partial calendar corruption.
19-07-26Timetable image route + TimetableReview confirm-before-save creating fixed weekly activities.Milestone: photo → review → immovable week path works. Adapted plan to keep human review mandatory.
21-07-26Grew Vitest suite for recurrence, status, grid, cycle, Zod, and AI schemas. Started public folio site structure.Challenge: keeping tests free of API keys so the teacher can run npm test offline.
22-07-26Fixed duration updates on existing items (minutes / end time). Logged regression case 12.1. Expanded folio (activity diagram, approach, finance, diary) and AI apply integration tests.Milestone: npm test green including integration apply path; folio content aligned to marking criteria.

Social, ethical and stakeholder considerations

Building a student planner is not only a technical problem. The people who touch the system — students, families, schools, and anyone marking or hosting the product — have different needs and risks. This section expands those considerations so design choices stay accountable to the problem we set out to solve: helping students organise real weeks without creating new harm.

Students as primary stakeholders

Students are the people whose homework titles, school subjects, and personal notes appear on the calendar. That data can reveal academic struggle, medical appointments, or family commitments. The product therefore isolates every query by authenticated user id, never stores passwords (one-time email codes only), and keeps API keys out of the repository. Students should be able to trust that opening the planner does not silently share their week with classmates or the wider internet.

There is also a wellbeing angle. An aggressive “optimising” scheduler could pack every free minute with study and increase stress. Student Time Planner is deliberately a guide, not a taskmaster: fixed school and sport stay put unless the student asks to move them, and overdue work is highlighted so it can be rescheduled rather than ignored or shamed.

Families and schools

Parents and teachers may want visibility into a student’s workload, but this version of the product does not expose shared dashboards. That is an ethical boundary as much as a feature gap: without clear consent flows, “helpful” sharing becomes surveillance. If collaboration were added later, it would need explicit invitations, least-privilege roles, and audit of who saw what.

Ethical use of AI

Gemini can misread a blurry timetable, invent subject names, or propose times that collide with school. Treating model output as ground truth would be unsafe. Mitigations baked into the design include: a human review step before timetable blocks are saved; Zod validation of every AI operation before any database write; all-or-nothing apply so a bad batch cannot half-update the week; and a hard rule that immovable activities are not shifted when the model is merely “making room” for study. The student remains responsible for their schedule; the AI is an assistant that must earn trust operation by operation.

Inclusion and accessibility

Colour alone must not be the only signal for overdue versus completed work — labels and actions accompany status colours. The week view is intended for both phone and laptop so students without a dedicated computer can still plan. Future work should deepen screen-reader labelling, focus order, and keyboard paths through the command bar and modals.

Operators and maintainers

Anyone running the stack (including a teacher or friend trying the demo) needs a path that does not require production email credentials — hence console-printed codes and a demo account. Automated tests document expected calendar behaviour so regressions like “Nothing to update on that item” for a duration change are caught before they confuse users again.

Algorithm solution

These algorithms describe how the product works end-to-end, not a single helper function. The mainline is what happens when a student opens and uses the planner. Algorithms A, B, and C are the three critical paths inside that mainline: building the week view, applying natural-language changes safely, and importing a timetable photo. Pseudocode uses capital keywords, paired structures (BEGIN/END, IF/ENDIF, FOR/NEXT), and indentation.

Mainline — using Student Time Planner

Overall control flow of the software solution from sign-in to an updated calendar.

BEGIN UsePlanner
  AuthenticateStudent
  LoadWeekView
  REPEAT
    Get student action
    CASEWHERE action evaluates to
      talk to planner: HandleAiRequest
      upload timetable: HandleTimetableImport
      complete or delete item: UpdateItemDirectly
      edit item in modal: UpdateItemDirectly
      change week: LoadWeekView
      OTHERWISE: ignore
    END CASE
    Refresh week view
  UNTIL student signs out
END UsePlanner

BEGIN LoadWeekView
  dates = Monday to Sunday for selected week
  items = read items for this student from database
  occurrences = ExpandWeek (items, dates, now)
  Display occurrences on day columns
END LoadWeekView

A. Expand week occurrences

What this is: how stored calendar data becomes the week the student sees. One-off blocks, recurring school series, skipped days, and overdue/completed status are all resolved here before anything is drawn.

BEGIN ExpandWeek (items, weekDates, now)
  occurrences = empty list
  FOR each item IN items
    ExpandItem (item, weekDates, now, occurrences)
  NEXT item
  Sort occurrences by start ascending
END ExpandWeek

BEGIN ExpandItem (item, weekDates, now, occurrences)
  IF item has recurrence THEN
    ExpandRecurring (item, weekDates, now, occurrences)
  ELSE
    ExpandSingle (item, weekDates, now, occurrences)
  ENDIF
END ExpandItem

BEGIN ExpandRecurring (item, weekDates, now, occurrences)
  FOR each date IN weekDates
    IF date IN item.exceptions THEN
      CONTINUE
    ENDIF
    IF date < recurrence.startDate THEN
      CONTINUE
    ENDIF
    IF recurrence.endDate exists AND date > recurrence.endDate THEN
      CONTINUE
    ENDIF
    IF weekday(date) not in recurrence.byWeekday THEN
      CONTINUE
    ENDIF
    IF interval > 1 AND week not on stride THEN
      CONTINUE
    ENDIF
    Apply overrides for date
    status = ComputeStatus (item.type, completed, end, now)
    APPEND occurrence to occurrences
  NEXT date
END ExpandRecurring

BEGIN ComputeStatus (type, completed, end, now)
  IF type <> task THEN
    RETURN upcoming
  ENDIF
  IF completed = true THEN
    RETURN done
  ENDIF
  IF end < now THEN
    RETURN overdue
  ELSE
    RETURN upcoming
  ENDIF
END ComputeStatus

B. Apply AI operations (all-or-nothing)

What this is: how the command bar turns a student’s message into real calendar changes. The model may propose several operations; the server validates every one first, then either writes the whole batch or writes nothing — so the week never ends up half-updated.

BEGIN HandleAiRequest
  message = student text from command bar
  response = AskGemini (message, current items, week context)
  result = ApplyAi (userId, response, context)
  IF result needs clarification THEN
    Show clarification to student
  ELSE IF result failed THEN
    Show error
  ELSE
    Show summary
  ENDIF
END HandleAiRequest

BEGIN ApplyAi (userId, response, context)
  ops = response.operations
  IF clarification exists AND ops is empty THEN
    RETURN ask user
  ENDIF
  plan = empty list
  FOR each op IN ops
    ValidateOperation (op)
    IF validation failed THEN
      APPEND error
    ELSE
      APPEND action to plan
    ENDIF
  NEXT op
  IF any error exists THEN
    RETURN error with no writes
  ENDIF
  FOR each action IN plan
    Execute action for userId
  NEXT action
  IF any write failed THEN
    RETURN error
  ELSE
    RETURN success with summary
  ENDIF
END ApplyAi

BEGIN ValidateOperation (op)
  CASEWHERE op.type evaluates to
    createItem: check item schema and duplicates
    updateItem: check item exists; allow title, colour, notes, duration
    moveItem: check movable or explicit
    deleteItem: check item exists
    skipOccurrence: check recurrence and date
    skipRange: check startDate and endDate
    completeItem: check type = task
    bulkShift: check itemIds and minutes
    OTHERWISE: reject unsupported type
  END CASE
END ValidateOperation

C. Timetable photo import

What this is: how a photographed school timetable becomes fixed weekly activities — only after the student reviews and confirms the draft, so a bad image cannot silently invent a full week.

BEGIN HandleTimetableImport
  image = uploaded timetable photo
  draft = AskGeminiVision (image)
  Show TimetableReview with draft subject blocks
  IF student cancels THEN
    RETURN without saving
  ENDIF
  confirmed = blocks student kept or edited
  FOR each block IN confirmed
    Create recurring activity (fixed, movable = false)
  NEXT block
  Refresh week view
END HandleTimetableImport

Version sequence / code backup

Source control is Git. The initial scaffold is committed locally; feature work was developed as dated milestones (table below) with the working tree backed up via the project folder and prepared for a submission zip / remote push. Each row records what changed and when, matching the project diary.

VersionDate / timeCommit / backup note
v0.1 Scaffold30-06-26 11:282fac498 — Initial commit from Create Next App
v0.2 Domain model05-07-26Checkpoint — Item/Segment/Recurrence types + Zod item schemas (lib/types, lib/validation)
v0.3 Calendar core08-07-26Checkpoint — expandWeek, exceptions, split sessions, fortnightly interval
v0.4 Week UI10-07-26Checkpoint — DayColumn, NowIndicator, ItemCard, ItemModal week grid
v0.5 Auth12-07-26Checkpoint — email codes, jose session cookie, proxy gate, demo login
v0.6 AI pipeline17-07-26Checkpoint — Gemini ops, Zod validation, all-or-nothing apply, command bar
v0.7 Timetable import19-07-26Checkpoint — image extract API + TimetableReview confirm-before-save
v0.8 Tests + folio22-07-26Checkpoint — Vitest unit + AI apply integration; public /folio; duration updateItem fix

Backup procedure: keep the Git history; export a zip of the repository for Schoolbox; do not commit secrets (.env.local stays local). Before final hand-off, batch-commit remaining checkpoints so the teacher can inspect history on their laptop.

Prototyping sequence

Prototyping moved from typed domain models to vertical UI slices rather than disposable throwaway screens.

  1. Backend / data prototype: Mongo item documents with segments vs recurrence; seed script builds a realistic demo week.
  2. Week view prototype: seven day columns, working-hour scaling, now-indicator, task checkbox and activity styling.
  3. Auth prototype: login form with code entry and demo path.
  4. AI prototype: command bar → JSON operations → validated apply; clarification messages when input is ambiguous.
  5. Timetable prototype: upload → draft blocks → review table → confirm creates immovable weekly activities.

Week view

Primary planner surface with day columns and command bar.

Screenshot slot

Login

Email code + demo CTA at /login.

Screenshot slot

Command bar

Natural-language entry under the week grid.

Screenshot slot

Timetable review

Confirm-before-save after image upload.

Screenshot slot

Automated testing, optimisation & evaluation

Automated tests prove the calendar core and AI apply pipeline behave as specified. Fixtures act as premade calendar items. Unit suites expand them for a frozen “now” and assert occurrences, statuses, grid geometry, and Zod shapes. Integration suites drive applyAiResponse with mocked persistence to prove validate→write behaviour (including all-or-nothing rejection). No manual steps and no API keys are required for npm test.

How to run

npm install
npm test

Result to record for evidence: the suite reports all tests passed across unit and integration files (100% of the automated suite). Example output shape:

Test Files  8 passed (8)
     Tests  35 passed (35)

Use npm run test:watch during development. npm test runs once and exits (suitable for demos).

Unit testing coverage

SuiteTestsWhat is tested
tests/calendar/recurrence.test.ts6Weekly school series, exceptions, overrides, split sessions, fortnightly interval
tests/calendar/status.test.ts4Overdue / done / upcoming; activities not completable
tests/calendar/grid.test.ts4blockPosition heights; overlapping lane assignment
tests/calendar/cycle.test.ts3Day 1–10 → weekday + Week A/B; fortnightly recurrence helper
tests/validation/item.test.ts6Zod accepts valid creates; rejects illegal shapes
tests/ai/operations.test.ts5AI response/operation schema rejects malformed ops
tests/ai/updateDuration.test.ts2Duration update on an existing item; empty update still rejected

Integration testing coverage

Integration tests sit above pure schema checks: they run the AI apply module end-to-end with the database layer mocked, so create / update / delete / reject paths exercise the real planning logic without needing MongoDB or Gemini.

SuiteTestsWhat is tested
tests/ai/applyIntegration.test.ts5Valid create writes; mixed valid+invalid batch writes nothing; immovable school not bulk-shifted; delete; clarification with empty ops
tests/ai/updateDuration.test.ts(shared)Also integration-style: applyAiResponse → updateItem patch for duration resize

Sample expected vs actual

Test caseInput (fixture)ExpectedActual
Weekday school expansionRecurring Mon–Fri 08:30–15:005 occurrences in a Mon–Sun weekPass (unit)
Skip exceptionSame series + exception on Wednesday4 occurrences; Wed absentPass (unit)
Overdue taskYesterday’s incomplete task; now = Wed noonstatus = overduePass (unit)
Duration updateEssay 1 Aug 16:00–17:00; minutes=240End becomes 20:00 (4 hours)Pass (integration)
All-or-nothing batchValid create + update missing idok=false; no DB writesPass (integration)
Invalid itemBoth segments and recurrence setZod failurePass (unit)

Optimisation

  • Validate AI output before any database write; fail closed on bad data.
  • Expand occurrences in memory for the visible week only — not the entire series history.
  • Clamp grid positions to working hours so off-hours blocks do not break layout.
  • Reject unknown item ids early so Gemini hallucinations never touch storage.

Feedback analysis and response

Manual AI prompts are logged in docs/calendarQueryTestCases.md. Section 12 is a regression log of real failed prompts. Example:

Feedback / failureAnalysisResponse
“make … on 1 August be like 4 hours” → “Nothing to update on that item.”Model sent updateItem with duration fields; apply only accepted title/colour/notes.Extended updateItem to accept minutes/timeEnd; added updateDuration + integration tests; documented case 12.1.
Model invents item ids or returns mixed good/bad opsPartial writes would corrupt the week.All-or-nothing apply + id existence checks; covered by applyIntegration tests.
Blurry timetable photos invent subjectsVision model is not ground truth.Mandatory TimetableReview confirm step; cancel writes nothing.

Evaluation

Against the functional requirements: FR1–FR9 are implemented in the running app; FR10 is this folio. Automated unit and integration tests give regression evidence for recurrence, status, validation, duration updates, and safe AI apply (FR3, FR6, FR8, FR9). Remaining risks include Gemini variability on poor timetable photos — mitigated by the review UI and Zod layer — and free-tier email limits in production, mitigated by the demo login path for marking.