Why architecture matters
Architecture is important because it turns an idea into a system that can be understood, built, and maintained. Before writing code, we must decide where the website, backend, authentication, automation, and data should live—and how they communicate. Clear architecture reduces repeated work, avoids unnecessary complexity, and gives every repository and service a specific responsibility.
Architecture is also the first layer of security and scalability. By separating the public frontend from the private backend, validating users through the API, and keeping credentials in secure storage, we protect both users and the company. Good architecture does not mean creating a complicated system; it means choosing the simplest structure that is secure today and capable of growing tomorrow.
The architectural decision
For the current stage, three repositories are enough. This separation keeps learning material open, production code focused, and sensitive backend work private.
Public learningswe-tickerbell
Public frontendswe-tickerbell-api
Private backendExternal services
Auth0 and Brevo
1. Become-SWE
This public repository contains lessons, decisions, mistakes, sanitized examples, and downloadable learning documents. It must never contain customer data, credentials, private dashboards, or confidential company information.
2. swe-tickerbell
This public repository contains the static website deployed through GitHub Pages: HTML, CSS, JavaScript, images, and public configuration. Public Auth0 identifiers may be used here, but no client secret, Brevo API key, or Google credential belongs in browser code.
3. swe-tickerbell-api
This private repository will contain the Python API, protected endpoints, authorization checks, integrations, tests, and Google Cloud deployment configuration. FastAPI on Google Cloud Run is the recommended starting point.
Core boundary: the browser may request an action, but the backend validates the request and performs privileged work. Secrets stay in Google Secret Manager, not in GitHub or frontend JavaScript.
How the services work together
- A visitor opens the static frontend hosted through GitHub Pages.
- Auth0 handles registration, login, password recovery, and access tokens.
- The frontend calls the Python API using a public or authenticated request.
- The API validates inputs and, when required, verifies the Auth0 token and permissions.
- The API obtains protected credentials from Google Secret Manager.
- The API communicates with Brevo or other services and returns a limited response.
Designing for a future Brevo replacement
The backend should use an email-provider interface instead of spreading Brevo-specific code across the application. The application calls the interface, while a separate Brevo adapter implements it. A future provider can replace that adapter without rebuilding the website.
Google Cloud structure
Start with Cloud Run for the Python API, Secret Manager for credentials, Artifact Registry for container images, and Cloud Logging and Monitoring. Use separate development and production projects, each with its own service account, secrets, logs, and Auth0 configuration. Add a database only when the application genuinely needs persistent data.
Avoid Kubernetes, multiple microservices, queues, and other infrastructure until a proven requirement appears. Simplicity is part of the security model because fewer components are easier to understand, test, and maintain.
Deployment workflow
- Develop each change on a feature branch.
- Open a pull request and inspect the diff.
- Run frontend or Python tests and security checks.
- Merge approved frontend changes to deploy GitHub Pages.
- Deploy backend changes to development first.
- Require approval before production deployment.
- Use GitHub OIDC and Google Workload Identity Federation instead of long-lived service-account keys.
Essential security rules
- Keep the learning and frontend repositories public, and the backend repository private.
- Protect the main branch and require pull requests and tests.
- Enable secret scanning, push protection, and dependency updates.
- Never commit
.envfiles, credential JSON files, tokens, passwords, or customer data. - Store runtime credentials only in Google Secret Manager.
- Validate every backend input and derive identity from a validated Auth0 token.
- Allow browser requests only from approved website origins.
- Do not log access tokens, passwords, full sensitive requests, or email addresses unnecessarily.
- Use separate development and production environments.
- Rotate a credential immediately if it is accidentally exposed.
What I learned
- Planning is not a delay before development; it is development work.
- Repository boundaries should follow responsibilities, not individual tools.
- Authentication identifies users, while backend authorization controls what they may access.
- A public repository cannot protect a paid or restricted PDF.
- Secrets belong behind the backend boundary.
- The best first architecture is the simplest one that is secure and can evolve.
Architecture checklist
- Draw the request flow before adding an integration.
- Decide which data is public, internal, personal, or secret.
- Assign one clear responsibility to each repository.
- Keep privileged calls in the backend.
- Define development and production environments.
- Document why each major technology was selected.
- Test the complete journey, not only the visible page.
- Review the architecture when the product requirements change.