2026-04-13 10:46:29 -05:00

6.4 KiB

name, description, license
name description license
vision-design Applies Vision's official design, standards, and application builds. Internal Use Only

Vision Application Design

Overview

Use this skill whenever developing for the Vision program — whether starting a new app, doing continual development on an existing one, or answering any questions about Vision. It covers architecture, design standards, authentication, app packaging, and backend conventions.

Keywords: vision, portal, dashboard, corporate identity, visual identity, post-processing, vision-frontend, vision-backendapi

When making UI elements, always invoke the brand-guidelines skill.


Projects

Vision is split into two separate projects:

  • Vision-Frontend — Houses all user interfaces, Django templates, session management, and user authentication. Does not store client data.
  • Vision-BackendAPI — Houses the REST API, data warehouse, ETL pipelines, and cron jobs. Stores all client data. Cannot be reached directly from the frontend.

Software Guidelines

Language and Software Foundation

  • Language: Python 3.11
  • Framework: Django 5.2.11
  • Database: Postgres (separate databases for frontend and backend)
  • Reverse Proxy: Nginx

Architecture

  • Frontend and backend are fully decoupled
  • Frontend communicates with the backend exclusively via API requests
  • Rendering is done through Django templates
  • Frontend database: user authentication and permissions only
  • Backend database: client data warehouse

Frontend Design

Layout

Vision uses a consistent three-region layout across all pages:

  • Left sidebar — navigation column, included via {% include '_sidebar.html' %}
  • Header — top bar, included via {% include '_header.html' %}
  • Main window — all app content renders here via {% block content %}

Template Conventions

All templates extend base.html:

{% extends 'base.html' %}

{% block extra_head %}
  {# App-specific CSS or meta tags #}
{% endblock %}

{% block content %}
  {# App UI renders here #}
{% endblock %}

{% block extra_scripts %}
  {# App-specific JavaScript #}
{% endblock %}

Key blocks:

  • extra_head — inject app-specific styles or meta into <head>
  • content — primary render target for all apps
  • extra_scripts — inject app-specific scripts before </body>

CSS and Styling

  • Custom CSS only — minimize third-party CSS dependencies
  • Follow brand colors, typography, and spacing from the brand-guidelines skill
  • Static files are served per-app from the app's own static/ folder

App Development

Development Philosophy

  • Vision has a core project and application
  • Additional features are built as separate Django apps
  • Apps are developed in isolation, then packaged and deployed to the main project
  • This prevents feature conflicts and allows simultaneous development

New App Structure

Every Vision app must include:

my_app/
├── static/
│   └── my_app/         # Namespaced static files
├── templates/
│   └── my_app/         # Namespaced templates
├── urls.py
├── views.py
├── models.py
├── apps.py
└── README.md           # Required: installation instructions

The README.md must document:

  • Any required entries in INSTALLED_APPS
  • URL routing configuration to add to the host project
  • Any required settings variables
  • Migration steps if models are included

App Scaffolding

New apps are generated from the Vision app template repo, which provides:

  • A pre-provisioned djangoappdev Django project for local development
  • Base templates matching the production layout (base.html, _header.html, _sidebar.html)
  • Base static files matching production

Always start new apps from this template repo rather than from scratch.

Packaging and Distribution

  • Apps are packaged as pip-installable packages
  • Distributed via Vision's private PyPI repository
  • Installed into Vision-Frontend or Vision-BackendAPI via pip

Security

Data Isolation

  • User authentication and permissions live in the Vision-Frontend database only
  • Client data lives in the Vision-BackendAPI database only
  • The backend database is not reachable from the frontend

Authentication — Wristband SSO

Vision uses Wristband for SSO and OAuth.

Frontend (Vision-Frontend):

  • Handles the full OAuth authentication workflow
  • Manages user sessions based on Wristband
  • On successful auth, receives and stores a bearer token
  • Includes the bearer token in all API requests to Vision-BackendAPI
  • Uses middleware to enforce session/auth requirements across views
  • Template {% if %} checks control whether UI elements are rendered based on user permissions/roles

Backend (Vision-BackendAPI):

  • Validates incoming bearer tokens by calling Wristband's API, which returns the user's email
  • Looks up that email in the Vision-Frontend database to verify permissions
  • Does not manage sessions directly

Permissions Model

  • Users are assigned to groups, each representing a tenant/client
  • Groups have memberships that grant tenants access to specific features
  • Groups have roles that grant individual users permissions within a tenant

Backend — Vision-BackendAPI

ETL Pipelines

  • ETLs pull vendor metrics for each client
  • Data is normalized into a standardized format and stored in the data warehouse
  • The data warehouse is consumed by Vision's custom LLM

Cron Jobs

The backend manages scheduled tasks including:

  • Refreshing and updating vendor data
  • Updating user information
  • Cleaning up stale data
  • Sending queued messages to external tools and notification systems

Technical Detail

URL Routing

  • Each app defines its own urls.py
  • Apps are registered in the host project's root urls.py using include()
  • Use app namespaces to avoid URL name collisions

API Communication (Frontend → Backend)

  • All requests include an Authorization: Bearer <token> header
  • The backend never trusts the frontend's claim of who the user is — it always validates the token with Wristband

Template Permission Checks

Use {% if %} guards in templates to conditionally render features:

{% if user_has_feature %}
  <a href="{% url 'my_app:index' %}">Feature Name</a>
{% endif %}

Never rely solely on URL access controls — template-level guards keep hidden features out of the rendered HTML entirely.