Yes. That is the right generic tool layer.
What you want now is a two-tier tool architecture:
Tier 1 — generic deployed Apps Script tools
These are reusable capability endpoints, not tied to any one entity.
Gmail • sendEmail • listEmails • getEmail • getAttachment • createDraft • replyEmail
Docs • createDoc • getDoc • appendDocContent • replaceDocContent • insertDocSections • exportDocPdf
Sheets • createSheet • appendRows • getRows • updateRows • findRows • logActivity
Calendar • createEvent • updateEvent • listEvents • getEvent • attachFileToEvent • createReminderEvent
Drive • createFile • copyFile • moveFile • shareFile • listFiles • exportFilePdf
⸻
Tier 2 — app-level orchestrators in your Next app
These are your real business actions.
Examples: • createTripAgendaAndInviteGuests • publishOfferAsPdfAndEmail • logMeetingAndCreateFollowup • buildClientBriefAndShare • createTripDaySchedule • sendPostSessionSummary
These should call the generic GAS endpoints through your own server actions.
⸻
Correct authority split
Apps Script • external Google Workspace executor • thin atomic actions • no business logic beyond validation and execution
Next server actions • business orchestration • entity-aware logic • document/trip/product/offer context • permissions • persistence in Prisma • revalidation
UI / toolbar / sections • intent launchers only • no direct Google logic • no secrets • no business rules
⸻
Best endpoint shape
Use one stable wrapper per tool, not many ad hoc routes.
Recommended pattern
POST /api/tools/google/gmail/send POST /api/tools/google/docs/create POST /api/tools/google/docs/export-pdf POST /api/tools/google/sheets/append POST /api/tools/google/calendar/create POST /api/tools/google/drive/share
Or if GAS is the executor:
POST /api/tools/google/run
with payload:
{ tool: "docs.create", input: { title: "Weekly Summary", content: "..." } }
But for maintainability, the first option is better.
⸻
Recommended atomic contract
Each endpoint should be: • single responsibility • deterministic • idempotent where possible • return machine-usable data • safe to call from document/trip/product flows
Example:
type CreateDocInput = { title: string; content?: string; folderId?: string; };
type CreateDocResult = { ok: true; documentId: string; url: string; };
⸻
What to build first
Build these first, in this order:
Round 1 • sendEmail • createDoc • appendDocContent • exportDocPdf • createEvent • appendRows • shareFile
Round 2 • listEvents • getRows • listFiles • createDraft • updateEvent • findRows
Round 3 • replyEmail • attachFileToEvent • copyFile • moveFile • replaceDocContent
That gives you the highest practical 20/80 coverage.
⸻
How this maps to your document system
A document toolbar command should never call Gmail/Docs/Calendar directly from UI.
Instead:
Toolbar click → Next server action → optional Prisma save / context resolution → generic GAS endpoint → store returned ids/links/meta in document/project/trip → revalidatePath
Example:
"Create meeting doc + invite" → createMeetingPackAction() → createDoc() → exportDocPdf() → createEvent() → sendEmail() → logActivity()
⸻
Generic metadata you should persist
Whenever one of these tools runs, persist traceability in your entities:
meta: { externalRefs: { googleDocId?: string; googleSheetId?: string; googleFileId?: string; googleCalendarEventId?: string; gmailMessageId?: string; }; }
That will matter later for: • updates • retries • exports • auditing • AI-assisted follow-up actions
⸻
Best fit for your toolbar and sidebar
Toolbar
Direct production commands: • Export PDF • Create Meeting • Send Summary • Share Doc • Schedule Event • Publish Offer • Trip Agenda
Sidebar tools
Context builders: • assistants • trip planner • product planner • experience planner • doc list • folders
So: • sidebar = compose intent • toolbar = execute intent • server action = orchestrate • GAS = perform Google side effects
⸻
Minimal deployment principle
Do not deploy 30 endpoints first.
Deploy 7 stable primitives first: • docs.create • docs.exportPdf • gmail.send • calendar.create • sheets.append • drive.share • drive.list
Then wire them into one or two real app flows.
⸻
Recommended folder structure
In your app:
app/(api)/tools/google/docs/create/route.ts app/(api)/tools/google/docs/export-pdf/route.ts app/(api)/tools/google/gmail/send/route.ts app/(api)/tools/google/calendar/create/route.ts app/(api)/tools/google/sheets/append/route.ts app/(api)/tools/google/drive/share/route.ts
In Apps Script:
doPost(e) handleDocsCreate(payload) handleDocsExportPdf(payload) handleGmailSend(payload) handleCalendarCreate(payload) handleSheetsAppend(payload) handleDriveShare(payload)
⸻
Final conclusion
Your plan is correct, but the key is this: • Apps Script endpoints = generic atomic capability layer • Next server actions = domain orchestration layer • Document/Trip/Product sections = context + payload sources • Toolbar = execution surface • Sidebar = composition surface
That is the right foundation for your next milestone.
Next best move: define the exact request/response schemas for the first 7 deployed endpoints.
<!-- ***** -->Atomic, Granular, Generic List of API Endpoints/Functions** A. Gmail API
-
users.messages.send — Send email (with/without attachments)
-
users.messages.list — List received/sent emails (filter by label/date)
-
users.messages.get — Get email details (for logging or follow-up)
-
users.messages.attachments.get — Retrieve attachments (e.g., PDFs)
B. Google Drive API
-
files.create — Create/upload files (Docs, PDFs)
-
files.export — Export Google Docs/Sheets as PDF
-
files.get — Retrieve file metadata (for sharing/logging)
-
files.list — List files/folders (for quick access)
-
permissions.create — Share files with users/groups
C. Google Docs API
-
documents.create — Create new Google Doc (meeting notes, reports)
-
documents.get — Retrieve document content (for logs/review)
-
documents.batchUpdate — Update document content (add meeting notes, outcomes)
D. Google Sheets API
-
spreadsheets.create — Create new sheet (activity log, tracker)
-
spreadsheets.values.append — Add new row (log activity, meeting outcome)
-
spreadsheets.values.get — Retrieve log data (for review/reporting)
-
spreadsheets.values.update — Update log entries
E. Google Calendar API
-
events.insert — Create/schedule calendar event (with invitees)
-
events.get — Retrieve event details (for follow-ups/logs)
-
events.list — List upcoming/past events (for activity review)
-
events.patch — Update event (add docs, change time, etc.)
-
events.attachments — Add attachments to events (via conferenceData or description links)
-
Add invitees
-
Attach Google Doc/PDF (via Drive link in description or as attachment)
3 Send email invitation with attached agenda/report (messages.send with attachment)
4 After meeting, update Google Doc with notes (docs.batchUpdate)
5 Share updated Doc/PDF with attendees (drive.permissions.create or messages.send)
6 Export Doc as PDF if needed (drive.files.export)
7 Review weekly logs in Sheets (sheets.values.get)
8 Send summary/follow-up emails (messages.send) 6. Custom Endpoint List (for your own API/middleware)
-
/send-email (params: to, subject, body, attachments)
-
/log-activity (params: activity_type, details, timestamp)
-
/create-doc (params: title, content, template)
-
/update-doc (params: doc_id, content)
-
/export-doc-pdf (params: doc_id)
-
/create-event (params: title, time, attendees, description, attachments)
-
/share-file (params: fileid, useremail, permission)
-
/get-logs (params: daterange, activitytype)
-
/send-followup (params: to, subject, body, related_event)
Summary Table:
Routine Step API Used Endpoint/Functionality Send/receive emails Gmail API send, list, get, attachments Log activities Sheets API append, get, update Create/update docs Docs API create, get, batchUpdate Generate/share PDFs Drive API export, create, permissions | Schedule events/invite | Calendar API | insert, get, list, patch, attachments|
| Share docs in events/email | Drive/Gmail API | permissions, send |
| Automate follow-ups | Gmail/Calendar | send, insert |
This toolkit covers 80% of weekly survival and growth actions for almost any business.
H1appscript-external-edge.skills.md
version: 2026.1 status: stable scope: appscript-webapps / doGet / doPost / deployments / nextjs-boundary / prisma-persistence / external-side-effects
H21. IDENTITY
Name: Apps Script External Edge Skill
Purpose: Define the bounded integration contract for Google Apps Script when used as an external executor alongside a Next.js + Prisma system.
This skill governs:
- private Apps Script functions
- public
doGet(e)/doPost(e)handlers - Apps Script web app deployments
- external calls from Apps Script to Next.js
- external calls from Next.js to Apps Script
- canonical persistence in Prisma
- side-effect containment for manager support, automations, and client updates
This skill does not define entity-specific business pipelines in detail.
Those belong in complementary pipeline skills.
H22. USE WHEN
Use this skill when the system includes one or more of:
- Apps Script web apps deployed as lightweight service endpoints
- Google-native automations that must still operate in Workspace context
- triggers for email, Drive, Docs, Sheets, Calendar, or admin workflows
- manager/operator helper endpoints
- user/client update automations
- webhook-like bridges between Google systems and Next.js
- a requirement that all externally produced or observed state be copied into Prisma for direct app access Do not use this skill for:
- internal UI-only flows
- pure server actions with no Google boundary
- heavy business logic design
- entity-specific pricing, document generation, or trip pipelines beyond the boundary contract
H23. CORE MODEL
Apps Script = external edge executor
Next.js = application authority
Prisma = canonical truth
Execution model:
Trigger / Google Event / Manager Action / External Request
→ Apps Script public handler
→ private router / validator / executor
→ Next.js external boundary or Google side effect
→ Next.js action layer
→ Prisma write / read
→ revalidate / projection / UI access
Reverse direction:
Next.js mutation or job
→ integration adapter
→ Apps Script endpoint
→ Google-native side effect
→ callback / result normalization
→ Prisma persistence of outcome
⸻
4. HARD INVARIANTS
4.1 Authority
page.tsx = read-only orchestration
components/ = dumb UI
actions/ = only mutation authority
Prisma = canonical truth
api/route.ts = external surface only
Apps Script = stateless or near-stateless executor
4.2 Required
* ALWAYS treat Apps Script as an edge integration, not truth
* ALWAYS persist canonical business state in Prisma
* ALWAYS persist important external outcomes back to Prisma
* ALWAYS keep public Apps Script handlers minimal
* ALWAYS push business logic toward Next.js compute/actions
* ALWAYS make Apps Script endpoints generic and granular by default
* ALWAYS promote specific pipelines into separate complementary skills when complexity grows
* ALWAYS validate payloads at both boundaries
* ALWAYS return normalized machine-readable responses
4.3 Forbidden
* NEVER let Apps Script be the only place where authoritative data exists
* NEVER keep canonical workflow state only in Sheets/Docs/Drive metadata
* NEVER expose private helper functions as public web handlers
* NEVER put heavy pricing, business rules, or entity ownership inside doGet/doPost
* NEVER call Prisma from anywhere except Next.js actions/server-side authority
* NEVER couple one web app deployment to one giant mixed pipeline if generic primitives are enough
* NEVER design Apps Script handlers around spreadsheet layout as domain truth
⸻
5. ROLE OF APPS SCRIPT IN THIS ARCHITECTURE
Apps Script is allowed to own:
* Google-native trigger entry
* Google account context
* Docs / Sheets / Drive / Calendar / Gmail execution
* thin request parsing
* thin action routing
* delivery formatting at the edge
* minimal manager support utilities
* lightweight status probes
* lightweight webhook relays
Apps Script must not own:
* canonical domain truth
* business entity lifecycle
* pricing truth
* order/offer/trip truth
* application state transitions as the only source
* long-term audit truth without Prisma copy
* multi-entity orchestration that should live in Next.js
⸻
6. PUBLIC VS PRIVATE APPS SCRIPT FUNCTIONS
6.1 Public Functions
Public means:
* doGet(e)
* doPost(e)
* optional installable trigger entrypoints
* optional menu handlers only for bound internal tools
Rules:
* keep them tiny
* parse input
* authenticate or verify shared secret/signature
* route to private functions
* normalize output
* catch errors centrally
6.2 Private Functions
Private means:
* all internal helpers ending in _ or namespaced within module objects
* request parsing helpers
* validation helpers
* Google side-effect executors
* response builders
* logging helpers
* integration adapters
Rules:
* no direct public exposure
* no assumption of canonical truth ownership
* no giant mixed orchestration unless explicitly defined as a dedicated pipeline skill
* must remain composable and granular
⸻
7. APPS SCRIPT DEPLOYMENT MODEL
7.1 Deployment Type
Preferred Apps Script deployment for this model:
Web app deployment
Use for:
* external HTTP invocation
* Next.js → Apps Script calls
* third-party → Apps Script calls
* manager/operator browser hits when a simple service endpoint is enough
7.2 Execution Bias
Bias toward:
Execute as the script owner only when the integration truly requires owner-level Google access
Reason:
* Drive / Docs / Calendar / Gmail actions often depend on Workspace permissions
* manager tools may need consistent access regardless of end-user Google scope
7.3 Access Bias
Prefer the narrowest access possible.
Typical modes:
* only authenticated workspace users for internal manager tools
* restricted trusted caller model for machine endpoints
* avoid broad anonymous endpoints unless the endpoint is intentionally public and low-risk
7.4 Deployment Separation
Prefer separate deployments for:
* internal manager/admin web app
* machine-facing service endpoint
* public low-risk content/status endpoint
Do not force all endpoint types into one deployment if security or clarity suffers.
⸻
8. doGet / doPost CONTRACT
8.1 doGet(e) Use Cases
Use doGet(e) for:
* health/status checks
* simple read-only probes
* browser-openable diagnostics
* HTML service UI when truly needed
* small read adapters returning JSON/text
* verification/ping endpoints
Do not use doGet(e) for:
* important mutations
* heavy side effects
* large payload processing
* stateful multi-step workflows
8.2 doPost(e) Use Cases
Use doPost(e) for:
* mutations
* Google-native execution requests
* delivery commands
* callbacks from external systems
* structured payload processing
* pipeline triggers
Do not use doPost(e) as a dumping ground for untyped giant blobs without routing.
8.3 Handler Shape
Preferred public shape:
doGet(e)
→ parseQuery(e)
→ authenticateRequest()
→ routeReadAction()
→ buildResponse()
doPost(e)
→ parseBody(e)
→ authenticateRequest()
→ routeWriteAction()
→ executePrivateHandler()
→ buildResponse()
⸻
9. MINIMAL ROUTING MODEL INSIDE APPS SCRIPT
Public handlers should route by an explicit action key.
Query example
GET ?action=status
GET ?action=doc-meta&id=abc123
POST { action: "send_email", payload: {...} }
POST { action: "create_calendar_event", payload: {...} }
Rules
* one public doGet
* one public doPost
* route internally using a small action registry
* keep action names stable and generic
* keep payloads typed by action
* reject unknown actions explicitly
Preferred Granularity
Default to 20/80 primitives such as:
* status
* fetch_doc
* write_sheet_rows
* create_doc
* export_pdf
* share_drive_item
* send_email
* create_calendar_event
* upsert_contact_note
* callback_result
Then layer pipeline-specific skills on top when needed.
⸻
10. RESPONSE CONTRACT
All Apps Script public handlers should return normalized output.
Preferred envelope:
type ExternalEdgeResponse<T = unknown> =
| { ok: true; action: string; data: T; meta?: Record<string, unknown> }
| { ok: false; action?: string; error: string; code: string; meta?: Record<string, unknown> }
Rules:
* always JSON for machine endpoints
* include action
* include stable code on failures
* avoid raw HTML unless intentionally serving UI
* do not leak stack traces in production responses
⸻
11. AUTHENTICATION / TRUST MODEL
At minimum, machine-facing endpoints should use one of:
* shared secret header
* signed payload pattern
* allowlist of known callers plus shared token
* Workspace session restriction for internal-only endpoints
Rules:
* authentication at the public handler
* authorization at the private action router
* do not rely on obscurity of deployment URL
* rotate secrets from configuration, not hardcoded constants
* log caller identity where possible
⸻
12. NEXT.JS SIDE CONTRACT
12.1 Boundary Placement
Use api/route.ts only for:
* external callers
* Apps Script callbacks
* webhook ingestion
* external machine-to-machine entry
Do not use api/route.ts for internal UI plumbing.
12.2 Canonical Internal Flow
api/route.ts
→ validate request
→ call action
→ action reads/writes Prisma
→ revalidatePath / revalidateTag
→ return normalized response
12.3 Internal UI Flow
client component
→ server action
→ Prisma mutation
→ optional integration dispatch
→ UI refresh
Apps Script is never the authority boundary for internal app UI.
⸻
13. PRISMA PERSISTENCE RULE
Every meaningful external action must map to one of these persistence patterns.
A. Canonical Record First
Prisma create/update canonical record
→ dispatch Apps Script side effect
→ persist delivery/execution result
Use for:
* offer send
* trip update notices
* manager-approved client notifications
* document generation commands
B. External Event First
Apps Script receives trigger/event
→ forwards normalized payload to Next.js
→ Next.js validates
→ Prisma persists canonical event / state / log
→ optional follow-up actions
Use for:
* Google-originated events
* manager sheet-triggered actions
* Workspace-native callbacks
* inbound automation results
C. Sync Backfill
Apps Script reads Google artifact state
→ pushes summary/callback to Next.js
→ Prisma stores copy for direct access
Use for:
* doc URLs
* calendar event IDs
* file IDs
* email dispatch status
* sharing outcomes
⸻
14. WHAT MUST BE COPIED INTO PRISMA
Persist to Prisma whenever the information matters for application access, audit, or continuity.
Examples:
* external job command
* delivery status
* file/document IDs and URLs
* email send attempts and outcomes
* calendar event IDs and sync state
* sync timestamps
* callback payload summaries
* manager/admin action logs
* error state worth surfacing
* last known Google artifact metadata
Do not rely on:
* “we can check the sheet later”
* “the Doc name contains the state”
* “Drive folder structure is the audit trail”
⸻
15. RECOMMENDED PRISMA MODELS
Adjust naming to domain, but keep the separation.
15.1 IntegrationEndpoint
Tracks registered external services.
15.2 IntegrationJob
Represents outbound request from Next.js to Apps Script.
Fields typically include:
* id
* provider
* action
* entityType
* entityId
* status
* requestPayload
* responsePayload
* errorCode
* errorMessage
* executedAt
* completedAt
15.3 ExternalEvent
Represents inbound event from Apps Script or Google-originated relay.
Fields typically include:
* source
* action
* externalId
* payload
* receivedAt
* processedAt
* processingState
15.4 ArtifactLink
Represents generated Google artifacts.
Fields typically include:
* entityType
* entityId
* artifactType
* googleFileId
* url
* metadata
* syncedAt
15.5 DeliveryLog
Represents user/client/manager delivery operations.
Fields typically include:
* channel
* target
* templateKey
* status
* payload
* providerMessageId
* sentAt
* errorMessage
⸻
16. NEXT.JS ACTION LAYER RESPONSIBILITIES
Actions must own:
* validation
* canonical entity mutation
* transactional safety
* recording integration jobs
* deciding whether to dispatch Apps Script
* writing back results
* revalidation
Actions must not delegate canonical ownership to Apps Script.
Preferred action flow:
validate input
→ open transaction if needed
→ write canonical entity state
→ enqueue or invoke integration
→ persist integration record
→ return result
⸻
17. TRANSACTION RULES
When a business mutation and an integration dispatch are related:
Preferred pattern
1. write canonical truth in Prisma
2. commit transaction
3. call Apps Script
4. persist external result
Why:
* truth exists even if integration fails
* retries are possible
* UI can show canonical state and delivery status separately
Avoid:
call Apps Script first
→ hope side effect succeeds
→ maybe persist later
Use transactions for dependent database writes on the Next.js side.
⸻
18. APPS SCRIPT MODULE SHAPE
Preferred module layout inside Apps Script:
PublicWeb_
doGet
doPost
RequestRouter_
routeGet
routePost
Auth_
verifyRequest
Response_
jsonOk
jsonError
Handlers_
status
createDoc
exportPdf
sendEmail
createCalendarEvent
callbackResult
GoogleDocs_
GoogleDrive_
GoogleMail_
GoogleCalendar_
Sheets_
Rules:
* public surface tiny
* routing isolated
* Google service wrappers grouped by capability
* handlers generic where possible
* pipeline-specific handlers live separately
⸻
19. GENERIC ACTION CATALOG (20/80 DEFAULT)
Use a small reusable action set before creating pipeline-specific endpoints.
Recommended default action catalog:
status
echo
create_doc
update_doc
export_pdf
write_sheet_rows
append_sheet_rows
share_drive_item
move_drive_item
send_email
create_calendar_event
update_calendar_event
record_callback
fetch_artifact_meta
Criteria for promotion into a dedicated pipeline skill:
* action requires domain-specific branching
* action spans multiple entities
* action needs sequence/state machine handling
* action has custom validation/business rules
* action includes multiple side effects that must remain coordinated
⸻
20. WHEN TO CREATE A COMPLEMENTARY PIPELINE SKILL
Create a separate skill document when the workflow becomes specific enough to deserve its own SOP.
Examples:
* Offer PDF + Drive share + email send
* Trip calendar build + share + callback sync
* Client update digest generation
* Manager approval → send sequence
* Sheet row ingest → canonical entity creation → outbound notifications
This bounded skill remains the shared external-edge contract.
⸻
21. NEXT.JS FILE PLACEMENT
External boundaries
app/api/<integration>/route.ts
Use for:
* inbound Apps Script callbacks
* outbound verification echo endpoints
* external webhook-style entry
Canonical domain slices
app/(pages)/<entity>/
page.tsx
actions/
components/
context/
types/
Integration modules
lib/integrations/appscript/
lib/integrations/google/
lib/validators/
lib/serializers/
Do not bury integration logic in UI components.
⸻
22. REQUIRED VALIDATION LAYERS
Validate at all of these levels:
Apps Script inbound
* action exists
* auth is valid
* required parameters present
* payload shape minimally valid
Next.js inbound
* source is trusted
* schema is valid
* entity references exist
* duplicate/replay handling considered
Action-level
* domain invariants
* permission checks
* entity ownership
* allowed transitions
⸻
23. IDENTITY / CORRELATION RULES
Every cross-boundary call should carry correlation metadata.
Recommended fields:
* requestId
* action
* entityType
* entityId
* source
* timestamp
Purpose:
* easier debugging
* idempotency handling
* callback matching
* audit continuity
⸻
24. IDEMPOTENCY / RETRY RULES
For machine-facing mutation endpoints:
* prefer idempotency keys when repeated calls are possible
* persist request identity in Prisma
* treat retries as normal
* do not duplicate emails/events/docs without checking prior state
Typical retry-safe operations:
* callback recording
* artifact link upsert
* delivery status update
* sync metadata update
⸻
25. OBSERVABILITY RULES
Log both sides, but persist only meaningful facts.
Apps Script logs
Use for:
* execution trace
* Google-side failure context
* quick debugging
Prisma persistent logs
Use for:
* business-audit trail
* user-visible delivery state
* manager-visible history
* retry tracking
* canonical external outcome
⸻
26. FAILURE MODES
Avoid these recurring failures:
* giant doPost containing all business logic
* separate truth living in Sheets and Prisma with no sync contract
* anonymous public endpoints with hidden side effects
* direct UI dependence on Apps Script-only state
* hardcoded deployment URLs all over the codebase
* no callback persistence after sending Docs/Emails/Calendar events
* mixing manager-support utilities with public client endpoints
* pipeline-specific logic polluting the generic action layer
⸻
27. DECISION RULES
When adding a new external Apps Script capability, decide in this order:
1. Is this truly Google-native?
2. Must Apps Script execute it, or can Next.js do it directly?
3. Is the operation generic or pipeline-specific?
4. What canonical entity owns the action?
5. What exact state must be copied into Prisma?
6. Is the endpoint read-only or mutating?
7. Should it be doGet or doPost?
8. Should this stay in the generic action catalog or become a dedicated pipeline skill?
Bias toward:
generic edge primitive
→ Prisma persistence
→ separate pipeline skill only when the flow becomes specific
⸻
28. OUTPUT CONTRACT
Any implementation derived from this skill must provide:
* a minimal public Apps Script handler contract
* private/internal function separation
* deployment access model
* action routing model
* Next.js external boundary placement
* Prisma persistence plan for external outcomes
* explicit canonical truth owner
* generic action catalog
* criteria for breaking out pipeline-specific skills
⸻
29. FINAL MODEL
Apps Script web app = external edge
doGet/doPost = tiny public gate
private functions = granular executors
Next.js api/route.ts = external intake only
Next.js actions = authority
Prisma = canonical truth + external outcome copy
Generic 20/80 actions first
Specific pipelines later as separate skills
⸻
30. TLDR
Keep Apps Script small, public, and generic.
Keep business truth in Next.js + Prisma.
Use doGet for light reads/status.
Use doPost for mutations and execution requests.
Persist all meaningful external outcomes back into Prisma.
Separate generic edge primitives from pipeline-specific skills.
Based on current official docs: Apps Script web apps are deployed as web apps, `doGet(e)` and `doPost(e)` are the public HTTP entrypoints, and Content/HTML services are the supported response mechanisms. Next.js App Router Route Handlers are the external request boundary, while Prisma supports transactional server-side writes for canonical persistence.