A website to view and approve to monument record sheet submissions
The submission app creates the Firestore document and review PDF under under-review/. This review app reads the review document and PDF, records review decisions, queues notifications and automatic county approvals, and publishes eligible submissions. The diagram shows the Firestore and Cloud Storage changes owned by each step.
flowchart TD
submitter[Submission app] -->|creates| submission[(Firestore: submissions/ID)]
submitter -->|creates| reviewPdf[(Cloud Storage: under-review/BLM_POINT_ID/SUBMITTER_ID/ID.pdf)]
submission --> review[Reviewer opens submission]
reviewPdf --> review
review -->|UGRC approves| ugrcApproved[Firestore update: status.ugrc.approved = true\nstatus.ugrc.reviewedAt / reviewedBy]
review -->|UGRC rejects| ugrcRejected[Firestore update: status.ugrc.approved = false\nstatus.ugrc.comments / reviewedAt / reviewedBy]
ugrcApproved --> updated{{onSubmissionUpdated}}
ugrcRejected --> updated
updated -->|approved| countyTasks[Queue auto-approval task\nQueue county notification email]
updated -->|rejected| rejectedEmail[Queue rejection email]
rejectedEmail --> rejected[Rejected\nPDF remains in under-review]
countyTasks --> countyNotice[County receives PDF attachment\nand review notification]
countyTasks --> autoApproval[After configured delay\nauto-approval task runs]
countyNotice --> countyReview[County reviewer opens submission]
reviewPdf --> countyReview
countyReview -->|approves| countyApproved[Firestore update: status.county.approved = true\nstatus.county.reviewedAt / reviewedBy]
countyReview -->|rejects| countyRejected[Firestore update: status.county.approved = false\nstatus.county.comments / reviewedAt / reviewedBy]
autoApproval --> automaticCountyApproval[Firestore update: status.county.approved = true\nreviewedBy = County*]
automaticCountyApproval --> mrrc{metadata.mrrc?}
mrrc -->|yes| stats[(Firestore: stats/mrrc-FISCAL_YEAR)]
mrrc -->|no| ready
countyApproved --> ready
stats --> ready[Both review approvals recorded]
countyRejected --> countyRejectedEmail[Queue rejection email]
countyRejectedEmail --> rejected
rejected --> forgive[Reviewer forgives rejection or user cancellation]
forgive -->|resets review approvals and cancellation| review
ready --> publishCheck{Daily publisher at 22:00 MT\nUGRC + county approved\ncounty approval >= 7 days ago\npublished = false}
publishCheck -->|not ready| wait[Remain in review\nPDF remains in under-review]
publishCheck -->|ready| agol[Update ArcGIS feature service]
agol --> movePdf[Move PDF to public path\ntiesheets/BLM_POINT_ID/GENERATED_NAME.pdf]
movePdf --> published[Firestore update: published = true\nstatus.publishedAt / publishedBy\nmonument = public PDF path]
classDef firestore fill:#e8f1ff,stroke:#2563eb,color:#172554
classDef storage fill:#fff4df,stroke:#d97706,color:#431407
classDef process fill:#eef7ee,stroke:#2f855a,color:#173b20
class submission,stats,ugrcApproved,ugrcRejected,countyApproved,countyRejected,published firestore
class reviewPdf,movePdf storage
class review,updated,countyTasks,rejectedEmail,countyNotice,autoApproval,countyReview,automaticCountyApproval,mrrc,ready,publishCheck,wait,agol,rejected,countyRejectedEmail,forgive process
- Install dependencies
pnpm installpnpm copy:arcgis
- Duplicate
.envas.env.localwith local secrets. - Install functions dependencies
cd functionspnpm install
- Duplicate
functions/.secretsas.secrets.localwith local secrets. - Start the website
pnpm start- Windows:
pnpm start-win- Note: If restarting pnpm, be sure to close the
cmdwindows that it opens first.
- Note: If restarting pnpm, be sure to close the
- Log in via Firebase in order to access the
Staff Revieweruserpnpx firebase-tools login --reauth- Select A and Yes, hit Enter, and click Allow on the browser popup
- Browse to the development server and login as
Staff Reviewer
- Create a site in firebase hosting
- Enable multi tenancy in the Google Identity platform
- Add credential created in apadmin to the tenant
- Update the authentication blocking functions after deployment
- Allow the storage rules to query the database in the firebase console
GitHub Actions installs dependencies for the standalone functions/ package before Firebase deploys, and firebase.json continues to use functions as the deploy source for both local development and CI.
To add new users:
- Ask the user to register on plss.utah.gov (or plss.dev.utah.gov in dev)
- Find the user's record in the submitters collection in firebase and update the elevated field to be true.
The following dependencies need to stay at the tailwind v3 versions
| Package | Tailwind 3 | Tailwind 4 |
|---|---|---|
| tailwind-merge | v2 | v3 |
| tailwindcss | v3 | v4 |
| tailwindcss-react-aria-components | v1 | v2 |
This project was developed with the assistance of GitHub Copilot.