Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: sirily11 <32106111+sirily11@users.noreply.github.com>
…ssibility identifier Co-authored-by: sirily11 <32106111+sirily11@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds documentation-only planning for introducing a new business card note type and a new add-contact note action, plus an iOS-focused frontend test plan to guide future implementation work.
Changes:
- Added an implementation plan covering backend schema/Zod/OpenAPI changes and iOS UI/view-model updates for
business-cardnotes andadd-contactactions. - Added an iOS frontend test plan (unit + UI) with sample payloads and proposed accessibility identifiers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| docs/BUSINESS_CARD_PLAN.md | End-to-end implementation plan (backend + iOS) with suggested file touch points and code snippets. |
| docs/BUSINESS_CARD_TEST_PLAN.md | iOS unit/UI test plan, including sample API payloads and a proposed accessibility identifier list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | `backend/app/api/v1/notes/route.ts` | No direct changes needed (Zod schemas handle validation automatically) | | ||
| | `backend/app/api/v1/notes/[id]/route.ts` | No direct changes needed (Zod schemas handle validation automatically) | | ||
| | `drizzle/migrations/` | New migration file for `business_card` column | | ||
| | `backend/next.openapi.json` | Regenerated via `./scripts/openapi-generate.sh` | |
There was a problem hiding this comment.
In the “File Change Summary”, backend/next.openapi.json is listed as being regenerated, but it’s actually the generator configuration checked into the repo; the generated spec is backend/public/openapi.json (gitignored). Updating this row will avoid confusion about which files are expected to change in an implementation PR.
| | `backend/next.openapi.json` | Regenerated via `./scripts/openapi-generate.sh` | | |
| | `backend/next.openapi.json` | Update OpenAPI generator config; run `./scripts/openapi-generate.sh` to regenerate `backend/public/openapi.json` (gitignored) | |
| | `business-card-first-name` | First name text field | | ||
| | `business-card-last-name` | Last name text field | | ||
| | `business-card-email` | Email text field | | ||
| | `business-card-phone` | Phone text field | | ||
| | `business-card-company` | Company text field | | ||
| | `business-card-job-title` | Job title text field | | ||
| | `business-card-website` | Website text field | | ||
| | `business-card-address` | Address text field | | ||
| | `action-type-add-contact` | Add Contact segment in action type picker | | ||
| | `contact-first-name` | First name field in action editor | | ||
| | `contact-last-name` | Last name field in action editor | |
There was a problem hiding this comment.
Accessibility identifier names in the test plan don’t match the existing convention used in the app (fields/buttons typically end with -field / -button, e.g. note-title-field, note-save-button in RxNote/RxNote/Views/Notes/NoteEditorView.swift). Consider renaming these planned identifiers (e.g. business-card-first-name-field, contact-first-name-field, etc.) to stay consistent and reduce UI test brittleness.
| | `business-card-first-name` | First name text field | | |
| | `business-card-last-name` | Last name text field | | |
| | `business-card-email` | Email text field | | |
| | `business-card-phone` | Phone text field | | |
| | `business-card-company` | Company text field | | |
| | `business-card-job-title` | Job title text field | | |
| | `business-card-website` | Website text field | | |
| | `business-card-address` | Address text field | | |
| | `action-type-add-contact` | Add Contact segment in action type picker | | |
| | `contact-first-name` | First name field in action editor | | |
| | `contact-last-name` | Last name field in action editor | | |
| | `business-card-first-name-field` | First name text field | | |
| | `business-card-last-name-field` | Last name text field | | |
| | `business-card-email-field` | Email text field | | |
| | `business-card-phone-field` | Phone text field | | |
| | `business-card-company-field` | Company text field | | |
| | `business-card-job-title-field` | Job title text field | | |
| | `business-card-website-field` | Website text field | | |
| | `business-card-address-field` | Address text field | | |
| | `action-type-add-contact` | Add Contact segment in action type picker | | |
| | `contact-first-name-field` | First name field in action editor | | |
| | `contact-last-name-field` | Last name field in action editor | |
| <MapPin className="h-4 w-4" /> | ||
| {note.businessCard.address} | ||
| </p> | ||
| )} | ||
| </div> |
There was a problem hiding this comment.
In the preview page snippet, MapPin is referenced for the address row but isn’t included in the shown lucide-react import. Since the snippet is labeled “additions only” and the real file already imports MapPin, consider updating the snippet to only add the new icons (e.g., Contact, Mail, etc.) or explicitly include MapPin so the example compiles as-written.
| <MapPin className="h-4 w-4" /> | |
| {note.businessCard.address} | |
| </p> | |
| )} | |
| </div> | |
| {note.businessCard.address} | |
| </p> | |
| )} | |
| </div> | |
| </div> |
| ### 3. Database Migration | ||
|
|
||
| A new Drizzle migration is required to add the `business_card` column and update the `type` column constraint. | ||
|
|
||
| ```sql | ||
| -- drizzle migration (generated via `bun run db:push` or drizzle-kit generate) | ||
| ALTER TABLE notes ADD COLUMN business_card TEXT DEFAULT NULL; | ||
| ``` | ||
|
|
||
| > Because SQLite stores enums as plain text, no ALTER is needed for the `type` column — the enum constraint is enforced at the application layer by Drizzle/Zod. | ||
|
|
There was a problem hiding this comment.
The migration section says it will “update the type column constraint”, but the SQL shown only adds business_card, and a few lines later notes that no ALTER is needed for type. Suggest rewording this section to avoid implying a DB-level enum constraint change in SQLite (or show the actual change if one is intended).
| .describe("Note type"), | ||
| note: z.string().nullable().optional().describe("Markdown note content"), | ||
| businessCard: BusinessCardSchema.nullable().optional() | ||
| .describe("Business card data (required when type is business-card)"), |
There was a problem hiding this comment.
The text says businessCard is “required when type is business-card”, but the proposed Zod NoteInsertSchema/NoteUpdateSchema keeps businessCard optional and doesn’t add a conditional refinement. Either add a Zod refinement to enforce businessCard presence when type === "business-card" (and optionally enforce note presence for text notes), or adjust the wording to match the actual validation behavior.
| .describe("Business card data (required when type is business-card)"), | |
| .describe("Business card data (used when type is business-card)"), |
| ./scripts/openapi-generate.sh # Regenerate backend/next.openapi.json | ||
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types |
There was a problem hiding this comment.
The OpenAPI regeneration note is inaccurate: backend/next.openapi.json is the next-openapi-gen config file, while the generated spec is written to backend/public/openapi.json (per outputDir/outputFile in backend/next.openapi.json, and it’s gitignored in backend/.gitignore). Please update the command comment and/or referenced path accordingly.
| ./scripts/openapi-generate.sh # Regenerate backend/next.openapi.json | |
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types | |
| ./scripts/openapi-generate.sh # Regenerate backend/public/openapi.json (OpenAPI spec) | |
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types from the updated spec |
| ./scripts/openapi-generate.sh # Regenerate backend/next.openapi.json | ||
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types |
There was a problem hiding this comment.
Minor but important: the plan suggests running ./scripts/openapi-generate.sh, but the current script in this repo contains a hard-coded absolute path (so it won’t work for other developers/CI). Consider updating the doc to instead reference cd backend && bun run openapi:generate (or fixing the script separately and keeping the doc).
| ./scripts/openapi-generate.sh # Regenerate backend/next.openapi.json | |
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types | |
| cd backend && bun run openapi:generate # Regenerate backend/next.openapi.json | |
| ./scripts/ios-update-openapi.sh # Regenerate Swift OpenAPI client types |
|
🎉 This PR is included in version 1.1.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Documentation-only plan for supporting business card notes alongside
regular-text-note, plus a newadd-contactaction type. No implementation changes.docs/BUSINESS_CARD_PLAN.mdBusinessCardstruct (firstName, lastName, email, phone, company, jobTitle, website, address) stored as JSON column onnotestableAddContactAction(type: "add-contact") — any note can include a button to save contact info to the user's address booknotes.ts), Zod validation (notes.ts), preview page rendering, migration forbusiness_cardcolumnActionEditorViewadd-contact form,NoteEditorViewtype picker + business card fields, view model updates, Contacts framework integrationExample of the new action in the discriminated union:
docs/BUSINESS_CARD_TEST_PLAN.mdOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.