DEV Community

AlexGR
AlexGR

Posted on

XP-R — Preparing the Foundations

Aviso: La mayoría de las actualizaciones estarán en inglés, pero iré publicando también entradas resumen en español cada cierto tiempo.

The last few work sessions on XP-R were mostly about preparing the
project's internal structure before real feature development begins.

A significant amount of time went into thinking through the architecture
before even installing Django. The goal was to make sure the backend
structure would work not only for the web platform, but also for future
components like the overlay, realtime features, and external
integrations such as a Discord bot.

It may look slow from the outside, but investing time here helps avoid
structural problems later.


Documenting Decisions

I also decided to start documenting architectural decisions using
Obsidian.

The idea is not to maintain extremely detailed technical documentation,
but to keep track of:

  • architectural decisions (ADRs)\
  • design reasoning\
  • ideas and future considerations

Basically, enough context so that if I step away from the project for a
while --- or if someone joins later --- the structure and reasoning
behind the system are still clear.


AI Tools and Development Workflow

After some research, I finally installed Antigravity to experiment
with its planning capabilities, mainly using the planner with Gemini
3.1 Pro
.

For now, I’ve decided not to adopt an agent-first workflow. Early stages of a project are usually the most fragile from an architectural perspective, and introducing autonomous agents too soon can easily create unnecessary complexity before the foundations are properly structured, though I might be mistaken.

The only exception is a security-focused agent that accompanies the development process, helping review potential vulnerabilities and risky patterns as the system evolves.

One interesting observation during these tests is that many AI tools
tend to apply generic OOP patterns to Django, ignoring how the
framework actually works internally. The Gemini 3.1 Pro (High)
responses were noticeably closer to real Django practices, which made it
more useful as a reference during architectural decisions.


Infrastructure Adjustments

I originally planned to start with Docker, but I'm working on a
cloud PC, and this environment doesn't allow virtualization, so that
idea was postponed for now.

Instead, the current stack looks like this:

  • PostgreSQL from the start (no SQLite phase)\
  • Redis in the cloud via Upstash (the same problem as with Docker)\
  • ASGI configured, with Django Channels ready

So even though the platform is still early, the backend is already
prepared for realtime features.


Project Structure

The Django project follows a modular monolith structure, grouping
apps inside a modules directory.

modules/
  identity/
    models/
    services/
    selectors/
    admin/
Enter fullscreen mode Exit fullscreen mode

Each module encapsulates its own domain and separates data models,
business logic, and read logic
.

The motivation behind this structure is simple:

  • High cohesion by domain\
  • Low coupling between modules\
  • Clear separation between models, logic, and read operations\
  • Preparation for organic growth of the modular monolith\
  • Possible future fragmentation into independent services\
  • Better mental clarity when thinking about the system at scale

This approach keeps the project maintainable as it grows, while still
leaving room for future architectural evolution if needed.


Identity Module

The first module implemented is Identity.

A custom user model was created before running any migrations,
including a UUID-based identifier that can be used consistently
across APIs, realtime channels, and potential future services.

To simplify realtime interactions, the user model also exposes a small
helper property used to standardize the user's realtime channel group:

@property
def realtime_group_name(self):
    return f"user_{self.user_id}"
Enter fullscreen mode Exit fullscreen mode

This avoids rebuilding the group name in multiple places across the
codebase and keeps the realtime layer cleaner.

The API layer also follows a simple rule from the beginning:
incremental database IDs are never exposed --- only UUIDs.


Overlay Architecture Considerations

One architectural question that remains open relates to the overlay
application
.

The web platform will likely continue using Angular, which works
well for complex dashboards and administrative interfaces. However,
overlays introduce very different constraints, especially when running
alongside a game like Star Citizen.

Angular's runtime behavior, including aspects of its garbage
collector, bundle and heavier runtime
, could potentially introduce
performance risks in that environment.

Because of that, I'm evaluating whether the overlay might instead use
something lighter like Svelte, while Angular remains responsible for
the web platform and dashboards.

This would mean running two frontend frameworks, which obviously
adds complexity, so the decision isn't final yet.

The desktop layer itself will most likely rely on Tauri, which seems
well suited for building a lightweight overlay-style application.
However, a few key capabilities still need to be verified, such as:

  • transparent windows\
  • click-through behavior when needed\
  • capturing input when required

In the near future I plan to build small prototype overlays that
simulate realistic UI load and realtime updates in order to test
performance under stress.


Current State

At this point the project has its basic foundation in place:

  • PostgreSQL database configured\
  • Redis cloud integration\
  • ASGI and Channels prepared\
  • Modular project structure\
  • Identity module started

Not a lot of visible features yet, but the structural groundwork is
now ready
, which should make the next development steps much smoother.


More Technical Notes

Some of the deeper technical details behind this setup are documented in a separate companion post -> XP-R — Preparing the Foundations (Tech Notes).

Top comments (0)