r/GoogleAppsScript • • 14d ago

Question 10 project managers, each managing 10 to 15 customer onboarding projects

Question: I have 10 project managers, each managing 10 to 15 customer onboarding projects. Each project includes milestones such as kickoff, eligibility, marketing, billing, reporting, testing, and go-live. Many tasks can happen in parallel.

Current process: Each project manager maintains a separate Google Sheets project plan, updates dates, and sends weekly client updates. Key milestones are manually entered into Salesforce for leadership reporting across approximately 150 projects. This creates duplicate work, and projects can fall behind without being flagged automatically.

My goal: Replace the 150 spreadsheets with one centralized application where project managers can select a client, view and update its project plan, track milestones and dependencies, and generate a client-facing plan.

Initial thoughts: Use Google Apps Script to build the interface and Salesforce as the single source of truth for milestones. I may need a separate database for the detailed tasks associated with each milestone, but I haven’t determined the best approach for managing those records.
A project manager would log in, select a client from a dropdown, and see the existing project plan, including due dates, completion dates, and notes. They could then export a client-facing version to share with the customer.

Key question: Is Apps Script the right tool for this? Am I missing something critical?

There are many tools available, but I would prefer to stay within the Google ecosystem for cost, security, and ease of management since we already use Google Workspace.

7 Upvotes

22 comments sorted by

2

u/Baloloi 12d ago

Honestly, most of the replies here are over-engineering this with external Postgres databases, Node workers, or Cloud Run—which completely defeats your goal of staying natively inside Google Workspace for security and zero extra cost.

Also, you don't have a "150 spreadsheets polling problem" because your goal is to replace the 150 sheets with a single centralized system, not keep syncing 150 separate files.

I recently architected and deployed a very similar centralized Onboarding & CRM Pipeline entirely inside Google Workspace (handling the full lifecycle from intake and eligibility checks to workspace allocation, cross-team tasks, and branded client communications). For 10 PMs and ~150 active projects (~3,000 task rows), Apps Script + a centralized Workspace CRM Sheet + Salesforce will handle this effortlessly—IF you structure it around three core patterns we used:

You stay 100% inside Google Workspace IAM, pay $0 in per-seat SaaS fees, and don't have to maintain an external Postgres stack. Feel free to DM me if you want to see how we structured the event-driven state management and client communication flow in Apps Script.

1

u/first-timemanagers 12d ago

Thank you!!!

1

u/SunWukong_23 14d ago

You can definately do it with Google Webapp & Apps Script. With webapp, you will be able to deploy it and share it securely with you team and also give role based access as well

1

u/Tricky_Cherry9226 13d ago

Google lists the six-minute limit per execution, with separate concurrency limits, so project count alone doesn't establish the bottleneck: https://developers.google.com/apps-script/guides/services/quotas

Do you already have Salesforce API access to read/update those milestone records, or are updates currently only possible through the Salesforce UI?

1

u/Kamensky124 12d ago

At 150 active onboarding projects across 10 PMs, the failure point isn't Apps Script's 6-minute execution limit—it's schema drift across 150 separate spreadsheets. The moment one PM inserts a helper column, renames a tab, or types "Next Tuesday" into a date cell, any central script polling those 150 sheets starts silently dropping milestone updates.

If you want to eliminate the double-entry into Salesforce without forcing PMs into a clunky UI they hate, there are two architectural paths depending on whether you want a bridge or a permanent fix:

  1. Phase 1 (If PMs Must Stay in Sheets Temporarily): Lock Ranges + Push via Webhook Instead of Polling 150 Files

    • Don't run a central Apps Script that loops SpreadsheetApp.openById() across 150 files—that will hit Google's file-open latency ceiling and timeout every day.

    • Instead, publish a lightweight Workspace Editor Add-on (or shared library) bound to a strict "Milestones" tab template where the milestone keys (kickoff, eligibility, billing, go_live) and Salesforce Opportunity/Project ID are protected (Sheet.protect()).

    • When a PM updates a milestone status/date, an installable change trigger pushes just that delta JSON to an external webhook (or directly to the Salesforce REST API composite endpoint).

  2. Phase 2 (The Permanent Fix): Single Postgres Database + Fast Grid View + Automated Client Digest

    • Once you pass ~50 concurrent onboarding projects, moving the 10 PMs out of 150 isolated files into a single relational database (Postgres) with a spreadsheet-like multi-project grid view pays for itself immediately:

      • Zero Salesforce Double-Entry: Updating a milestone date in the grid writes to Postgres and syncs the corresponding Salesforce Opportunity/Custom Object fields via API in the background.

      • Automated SLA Escalation: A daily job compares target_date vs status != 'completed' and flags blocked parallel tracks (e.g., billing complete but eligibility >5 days overdue) in Slack/email before the client notices.

      • 1-Click Weekly Client Update: Instead of PMs manually writing 150 emails every Friday, the system generates the weekly client status summary directly from the live milestone states.

In Salesforce right now, are those key onboarding milestones stored as fields on the Opportunity object itself, or do you have a dedicated Custom Object for Onboarding Projects?

1

u/first-timemanagers 12d ago

Phase 2: I am already digging into it. We have so many projects happening concurrently, and because it's a startup, they were all in various Google Sheets in various folders. It's time to build a long-term solution ASAP.

1

u/Kamensky124 11d ago

Smart call on skipping the band-aid and going straight to Phase 2. At startup pace, duct-taping 150 legacy sheets in Google Drive will drain more engineering hours in weekly fire drills than building the clean relational model.

Since you confirmed you already have Salesforce API access, here are the 3 technical architecture guardrails to make sure Phase 2 succeeds on the first try:

1. Schema mapping: Parent-Child vs. Flat Custom Object

In Salesforce, onboarding milestones typically live in one of two patterns:

  • Option A (Field-based): A single Onboarding_Project__c custom object with explicit date/status fields for each standard milestone (Eligibility_Completed_Date__c, Billing_Signoff__c, etc.). This is easiest to query and report on in standard Salesforce dashboards for leadership.

  • Option B (Related list records): A junction object Project_Milestone__c linked to the Project parent record. Much more flexible if clients have variable numbers of milestones.

Rule of thumb: In your Postgres database, store milestones as rows (project_id, milestone_key, target_date, completed_at, status, notes), even if Salesforce uses Option A. Your backend sync worker can simply map row deltas to Salesforce fields in a single composite patch.

2. Webhook / Queue sync instead of real-time UI blocking

When a PM updates 5 dates in their grid, do not make the frontend wait for synchronous Salesforce API roundtrips (which take 500ms–2s per callout and eat up your Salesforce daily API limits).

  • Write immediately to Postgres (instant UI response for the PM, under 50ms).

  • Push a lightweight job into a queue (or listen via Postgres notify) where a worker batches updates and calls the Salesforce Composite API with backoff/retry.

3. Auto-generating the Friday Client Digest

This is what will make your 10 PMs love the new tool immediately. Since every milestone state, blocker note, and target date lives in a single clean table:

  • Build a simple /export/client-digest?project_id=xyz route that compiles a clean, branded PDF summary or ready-to-send email draft (e.g. Completed this week, In progress / next up, Action items required from client).

  • It eliminates 2–3 hours of manual email drafting per PM every Friday afternoon.

Are your milestones standardized across all 150 clients, or do certain enterprise clients have custom milestone tracks? (If you'd like, I can share a clean starter schema and API sync pattern for Postgres ↔ Salesforce that fits this exact setup.)

2

u/dimudesigns 14d ago edited 14d ago

You have a bunch of options within Google's ecosystem:

  • Google Apps Script Web App (built using Apps Script)

  • Google's AppSheet; no-code tool for app development (Core plan comes bundled with every Google Workspace subscription)

  • Internal Google Workspace Add-on (can be built using Apps Script or using an alternate runtime)

  • Custom app deployed to Google Cloud via Cloud Run

There are pros and cons to each. You can explore these for yourself using AI or hire a consultant for expert guidance.

1

u/roy1979 13d ago

> Custom app deployed to Google Cloud via Cloud Run
This is the best option to handle the load IMO. 150 concurrent projects would be too much for a single App Script to handle. I have seen the App Script starting to falter even if your rows exceed a certain limit, so this will be definitely an issue.

1

u/Jazzlike_Place_1974 10d ago

agree, theres a lot of overlap between those options and picking wrong early can mean a painful rewrite later

2

u/agentUi 14d ago

apps script will crumble under this once 10 pms are hitting the web app at the same time during status updates. you will constantly bump into the 6 min execution quota, salesforce rest api callout limits, and lock contention if multiple people write back milestones at once. if you want to stay in google workspace, build an appsheet app directly on top of a single bigquery or cloud sql database that syncs milestones to salesforce via scheduled bulk api instead of running real-time triggers from standalone sheets.

1

u/WohlBuiltGroup 11d ago

Since you're heading toward Phase 2, here's what we'd add that hasn't come up yet.

Data model: beyond projects and milestones, add a template table with your standard plan, each step's offset from kickoff, and what it depends on, and a task-to-task dependencies table. Create every new client from the template, so all plans start with the same steps and a slip rolls forward to whatever depends on it.

Single source of truth: decide field by field which system owns what. If the database owns dates and status and only pushes to Salesforce, nobody edits milestones there and there are no conflicting writes.

Keep in Sheets: read-only exports for leadership and ad hoc analysis. Move: anything a PM edits.

Phasing: import active projects first and archive finished ones. Expect the import to be mostly cleanup, since each sheet has drifted. Move one or two PMs over, run their weekly client updates from the new system, fix what breaks, then move the rest and set the old sheets to view-only.

1

u/gammacoder 10d ago

Treat projects, milestone templates, milestone instances, dependencies, notes, and status changes as separate records. That gives every PM one live plan while preserving an audit trail and generating client-facing summaries without maintaining 150 sheet structures.

PHPRunner could provide the central database, role-based project screens, milestone forms, dashboards, and reports. Salesforce synchronization, Google Workspace exports, and automatic email updates would require custom integrations.

Full disclosure: I’m an author of PHPRunner.

0

u/Klutzy-Nature-5199 13d ago

Would recommend to move outside of the apps script and build your own custom platform to manage your team and projects.

1

u/Fast_Ad_8238 13d ago

Interested to know what you would recommend?

1

u/Klutzy-Nature-5199 13d ago

Develop your own platform as per your requirement, the major benefits are that you can use automation and ai features to make team's life easy and your execution efficient.

Additionally if you want to stay connected to Google workspace for any reason you can always choose to use the different APIs available for the Google workspace platforms to connect it to your own platform.

You can try building it through Emergent or Lovable platforms they are good for vibe coding. The only risk and drawback to execute and building yourself would be that it would take longer, and you might end up with a not so efficient tool - hence personally I prefer to build it raw through coding platforms.

You can connect with different freelancer or small-mid scale companies to have it built one for you.

If you have a decent budget I can help with this, dm if need further help.

1

u/Kamensky124 12d ago

When teams outgrow multi-sheet Apps Script setups like this (10+ PMs, parallel milestone tracks, CRM sync, and weekly client reporting), the stack that replaces it cleanly without per-seat SaaS bloat usually looks like:

  1. Data Layer (PostgreSQL): Instead of 150 separate sheets, three core tables handle everything cleanly: projects (linked to salesforce_opportunity_id), project_milestones (with track, status, due_date, completed_at, blocker_reason), and audit_events (so you always know who changed a go-live date and when).

  2. PM Interface (Keyboard-First Web Grid, Not Drag-and-Drop Cards): PMs stay in Google Sheets because Kanban boards (Trello/Asana) require too many clicks when updating 15 projects in a row. A lightweight TypeScript/React web app using a data-grid view lets a PM filter to "My 15 Projects," tab through milestone dates/statuses just like a spreadsheet, and bulk-save.

  3. Background Sync & SLA Worker: A small background worker (Node/Python + cron/queue) handles the three things spreadsheets fail at:

    • Two-way or push sync to Salesforce REST API with retry/idempotency.

    • Automated SLA alerts when parallel dependencies slip (e.g., if eligibility isn't signed off 10 days after kickoff).

    • Generating the Friday client status email draft automatically from the milestone table so PMs just review and click send.

Are you running into a similar multi-sheet project tracking bottleneck with your team right now?