// Evidence Dossier
Occupational Risk Prevention Website
From service enquiries to self-managed content: a professional website with phone-based editing, service and sector pages, and direct contact. End-to-end development and production deployment; local technical validation with explicit limits.
- Who it serves
Soledad Barrera, an occupational risk prevention consultant in Atacama, and companies looking to understand her services and contact her.
- My responsibility
Individual end-to-end development: public interface, content panel, Firebase integration, technical SEO and deployment.
- Current status
Website and panel in active production with phone-based editing. This review tested an isolated local copy.
- What it enables
The consultant can maintain her offering without requesting code changes. Visitors find services and a direct enquiry path. No commercial metrics are available.
Context
A professional services website should help a company understand what it can commission, where the service is provided and how to start a conversation. Here the audience is companies in Atacama looking for occupational risk prevention advice; the administrator is the professional responsible for that offering.
The code presents services, sectors, experience, FAQ and contact. Statements about professional experience and testimonials are commercial content from the source website; this software review does not audit those statements or certify regulatory compliance.
Problem
The problem addressed is maintaining an owned, understandable digital presence, with a clear service-to-enquiry path and editing without code changes. The panel prevents every content update from depending on another developer delivery.
There is no measurement of the previous process or before-and-after commercial comparison. The outcome is therefore stated as delivered capability and reported use, without attributing increased sales or a quantified workload reduction.
My role
I completed the project end to end as sole developer: website design and programming, panel, content and image integration, SEO preparation and production delivery.
Version history explains changes in authentication, Firebase compatibility, mobile administration and indexable pages, documenting implementation decisions and code evolution.
Constraints & mobile autonomy
Phone-based editing needed to fit the work of a professional who does not administer infrastructure. The panel organises sections into forms, provides links to the public view and offers a mobile save control. The interface preserves the consultant’s identity.
Managed services reduce server work but do not establish zero cost: quotas, billing and provider terms were not reviewed. Firebase, email and external channels retain their own dependencies. Validation used an isolated copy without operational credentials or data.
Solution
The solution combines a service homepage, dedicated service and sector pages, FAQ, a form and contact links. The panel edits text, visibility and photographs, saving sections through the server.
The public flow was checked on a local production build: home → service page → contact → form validation → visible response. Success and network failure used an intercepted provider. Real modules also exercised save → reread → supply content to the public layer, with simulated storage.
Architecture & diagrams
Next.js 16.3.2 uses App Router, React 19.2.3 and TypeScript, with Tailwind CSS v4 for the interface. The server obtains sections from Firestore and merges fields with default content; remote data is validated before delivery to components. Firebase Auth, Firebase Admin and Storage support identity, server operations and images.
The 13 sections are read in parallel. The homepage configures regeneration every 300 seconds and saving requests its invalidation. Service and sector pages read their specific copy and shared configuration from code files rather than the CMS. Panel edits do not update that configuration in these views. The diagram describes implementation rather than measured cloud availability.
Read the diagram and its limits
Visitors reach the public website and contact channels. The consultant edits the panel using Firebase Auth. The Next.js server saves sections to Firestore and images to Storage. The public website reads sections; defaults are available when a read rejects.
WhatsApp is a separate contact channel; form data goes to Web3Forms. Images are public resources. Default content is not a copy of the latest edit.
Implementation map. System in active production; local identity, storage and contact checks used doubles.
Concurrency, integrity & recovery
Default content supports rendering without Firebase configuration and recovering from rejected reads or invalid stored content. This was checked with the real reader and simulated failures. It does not retain the latest valid edit or impose its own maximum wait for a pending remote read.
Saves replace a complete section. Two overlapping requests reached a barrier in the storage double and were both accepted; no version conflict detection exists in that flow. This tests application control, not concurrency against real Firestore.
A simulated failure after persistence returned an error while content remained saved. Image uploads also contain separate steps, so an object can remain stored if publication fails. Automatic recovery, version history and orphan-file removal were not established.
Decisions & tradeoffs
Server content with defaults: keeps a public representation and avoids relying solely on browser queries. The tradeoff is potentially outdated fallback content. A wholly static site would be simpler but would not provide consultant-managed editing.
Firebase as a managed service: combines identity, documents and images and reduces server administration. A custom backend would provide more operational control at the cost of maintenance; no formal provider comparison was found.
Service and sector pages: a subsequent iteration added routes, metadata and structured data. This favours readable, indexable content, but specific copy still requires code changes. Evolution also separated authentication module loading to prevent public rendering errors.
Motion and GSAP organise interactions and animations, while Lenis handles scrolling. The frontend report documents preserving identity and avoiding a 3D environment without value for this website. No numbered ADRs were found; these are tradeoffs observed in code and history, not invented documents.
Security & privacy
Administrative identity and authorisation are checked on the server before saving. The code includes content structure validation, input limits and image checks. Included rules separate public content reads from writes. Their effective Firebase deployment was not checked.
Denied responses and state preservation for invalid input were tested with identity and storage doubles. This does not replace independent provider review or establish absolute protection. Published images are public resources; their validation is not comprehensive file analysis.
The form sends enquiry data to Web3Forms. WhatsApp is a different provider and conversation. Browser checks intercepted submission and responded locally without real email. The case study excludes credentials, account data and reserved operational details.
Testing & verification scope
Based on the technical review against the recorded local state. The remote repository pointed to the same version. Code was copied to a persistent Windows laboratory and lockfile versions installed with installation scripts disabled. Environment files were excluded. Node.js 22.23.2 and npm 10.9.8.
The original suite passed 13/13 tests across four files: six content checks, one removed-cursor check, two import/header checks and four SEO/runtime checks. Some inspect source text; they do not establish functioning external services. The 12 additional tests imported real modules and replaced Firebase and cache invalidation with doubles.
The build generated 22 static entries; types passed and ESLint reported four warnings. The browser checked the local website on desktop and mobile, a service, native form validation, intercepted contact success and network failure, the menu with Escape and login redirection. Firebase emulators, real authentication, a signed-in browser panel workflow, email delivery and a reproducible Lighthouse benchmark were not executed.
| Check | Result | Scope |
|---|---|---|
| Original suite | 13/13 · 4 files | 6 content; 1 removed cursor; 2 imports/headers; 4 SEO. Includes source inspection. |
| Additional checks | 12/12 | Real modules; simulated identity, storage and cache. Includes scenarios reproducing limitations. |
| Static analysis and types | 0 errors · 4 warnings | Two unused imports, internal navigation and native image usage. TypeScript passed. |
| Build and startup | Passed · 22 static entries | Next.js 16.3.2. No Firebase credentials: default content rather than production data. |
| Public flow | Checked in browser | Service → mobile contact; native validation; intercepted success and network failure; menu and login. |
| Published sample | 4/4 per language | Exact displayed code and test executed. Educational adaptation, no network. |
| Production and results | In production / no metrics | Website and panel in active use with phone editing. No conversion, availability or Lighthouse measurement. |
Deployment & operation
The website and panel operate in production and support phone-based editing. Vercel and Firebase belong to the delivery architecture described by the project; this local technical review did not inspect remote accounts, cloud deployments, applied rules, quotas or operational logs.
The production build started locally on loopback without credentials, using default content. Defensive headers and panel redirection to login were observed. Preventing indexing of an administrative page is not access control. Invalidating the homepage does not establish simultaneous updates across all routes.
Outcome & professional impact
The delivery lets the consultant present her offering through an owned website and maintain content from her phone in active production. My contribution connected that autonomy with a public service and contact experience and addressed integration and delivery needs.
No visits, enquiries, contracts, time savings or commercial return metrics are available. Lighthouse scores and zero-cost or continuous-availability guarantees without reproducible measurements were removed. Local results are engineering evidence under the stated conditions.
Evidence & limits
Implemented: public site, editable panel, content reads, validation, technical SEO and image uploads, observed in the reviewed version.
Locally checked: 13 original tests, types, build, startup and public flow. The 12 additional checks exercise real code but depend on the described doubles. The visible sample passed its four cases in both languages.
Simulated: Firebase identity, document and image persistence, post-save failures, cache and contact-provider responses. No real cloud service was stopped or tested.
Operational status: individual development, production use of website and panel, and phone-based editing. Pending: commercial metrics, Lighthouse under recorded conditions, comprehensive accessibility audit and a signed-in workflow with real Firebase. Results and the laboratory are retained in a sanitised internal record; evidence is explained on this page.
Failure and concurrency checks
The two saves overlapped inside the test process, but storage was a double. Both saves were accepted. Simulated failures exposed persisted state and retry behaviour; they do not establish provider capacity, availability or transaction behaviour.
Operational observations & mobile autonomy
Production and phone-based use represent the real operational state of the delivered system. The local browser checked presentation and contact with default data. The video is presentation material and the screenshot shows the local public website; neither establishes the state of a real remote administrative account.
Software quality & mobile UX
Editing groups content by section, displays save confirmation and errors, and provides mobile controls. The public site organises services and FAQ through links and labelled forms; mobile navigation closed with Escape. On simulated contact failure, the form retained the entered data and displayed an error.
Lenis avoids animated scrolling when reduced motion is requested; that does not establish that every animation respects the preference. At 1280 px a word break was observed in the source website’s animated heading, while it was fully readable at 1440 px. Product repairs fall outside this request. No WCAG certification or accessibility score is assigned from this partial review.
The case study separates decisions, checks and limits, with an index, mobile-readable diagram, independently scrolling table and wrapping code. Technical documentation is not offered as page downloads.
Code sample & engineering test
A small educational adaptation of public reading with default content. It uses already validated synthetic data and an injected read function: merges fields or recovers defaults when a read rejects. It does not reproduce Firebase access, full CMS validation or a timeout.
Requirement: Node.js 22 or later. The first block and its test form one module; the exact displayed text was executed. No auxiliary files, credentials or external connections are needed.
// Node.js 22+. Synthetic, already validated content. |
async function readPublicSection(read, defaults) { |
try { |
const stored = await read(); |
return { ...defaults, ...(stored ?? {}) }; |
} catch { |
return { ...defaults }; |
} |
} |
Isolated sample test
import assert from 'node:assert/strict'; |
import { test } from 'node:test'; |
|
const defaults = { heading: 'Services', visible: true }; |
test('stored content retains missing defaults', async () => { |
const read = async () => ({ heading: 'Training' }); |
assert.deepEqual(await readPublicSection(read, defaults), |
{ heading: 'Training', visible: true }); |
}); |
test('missing document uses defaults', async () => { |
assert.deepEqual(await readPublicSection(async () => null, defaults), defaults); |
}); |
test('rejected read uses defaults', async () => { |
const read = async () => { throw new Error('Simulated outage'); }; |
assert.deepEqual(await readPublicSection(read, defaults), defaults); |
}); |
test('inputs remain unchanged', async () => { |
const stored = { heading: 'Training' }; |
const result = await readPublicSection(async () => stored, defaults); |
result.heading = 'Edited'; |
assert.equal(stored.heading, 'Training'); |
assert.equal(defaults.heading, 'Services'); |
}); |
4/4 cases passed: missing fields, missing document, rejected read and preserved inputs. Spanish and English use the same sample. This verifies the example; additional project checks use its real modules and are recorded separately.