Skip to content

Repository files navigation

Studymation

A Mexican student pastes their assignment brief and the teacher's rubric. Studymation turns that into a finished, formatted Word document — institutional cover page, structured sections, and citations that were actually looked up in academic databases rather than invented by a language model.

The guided brief: topic, subject, student data, academic context and the teacher's rubric pasted in full, with a readiness panel showing 7 of 7 required fields

The brief is the product's contract with the student. The rubric is not a "notes" field: it is parsed into a list of deliverables that the pipeline must satisfy and that a later step audits. Attachments (the PDF the teacher handed out) are parsed and used the same way.


From brief to .docx

Pipeline: understand the assignment and its rubric, write in phases, verify citations against real academic sources, and deliver a .docx

The pipeline is not one giant prompt. Each stage is a step with its own model configuration, its own failure mode and its own audit trail — and which steps run at all depends on what was asked for. A GenerationProfile derived from the document type decides whether the document needs a thesis plan, an introduction, a conclusion, an overlap check between sections, or citations. A one-page answer and a research essay go through genuinely different pipelines, not the same pipeline with a different word count.

Generation screen showing the real backend state: analysis and structure completed, content generation in progress

The progress screen is not an animation: it polls the document's real current_step, so what you see is the stage the backend is actually on.


The deliverable

Two pages of a generated document: the CETI institutional cover page with the student's data, and the body with headings, an in-text citation and the references section

Word is the format Mexican schools ask for, so the output is a real .docx built with python-docx: cover page from the school's own template, heading styles, tables, charts and diagrams when the document calls for them, in-text citations and an APA 7 reference list that only contains sources marked as used.

(The document above was produced by running the assembler step with the repository's own test fixtures — cover, styles, citation and reference page are the system's output; the prose is fixture text, since this environment has no LLM keys.)


What makes it more than a prompt wrapper

Citations are found, ranked and validated — or reported as missing. Candidates come from Semantic Scholar, Crossref and Brave, are deduplicated, scored against the section they would support, and revalidated even when they come from cache. A DOI that resolves is only one signal; relevance decides. If nothing survives, the section is recorded as found=False with the rejection reasons and the reference list does not grow. The audit is stored with the document and exposed at GET /api/v1/documents/{id}/citation-audit.

The rubric is a contract. ContractValidationStep re-reads the finished content against the deliverables extracted from the rubric and logs auditable warnings (contract_deliverable_missing, contract_deliverable_constraints_violated, contract_duplicate_sections) instead of silently shipping a document that ignored half the assignment.

The quality gate never blocks delivery. A terminal step scans the rendered .docx for artifacts a student would notice — raw Mermaid, unresolved placeholders, stray markdown, charts without provenance — and reports them. The student still gets the file; the issue gets logged.

Content is written in phases. Global plan (thesis and claims per section), sections in parallel with awareness of their neighbours, then introduction and conclusion written from what the sections actually say, then a Jaccard overlap check that rewrites sections that say the same thing twice.


Around the pipeline

Layer What is there
Accounts Email + password or Google OAuth, JWT in an HttpOnly cookie
Plans free, pro, max — plan-gated features, per-plan rate limits and per-plan LLM models
Credits 1 credit = 1 MXN, immutable ledger, SELECT FOR UPDATE on balance, idempotent by reference id
Payments Stripe Checkout for both subscriptions and credit packs, webhook with signature validation
Schools Each institution is a folder (backend/schools/<id>/school.json) with its own cover format, colours and logo
Attachments .txt, .md, .pdf, .docx parsed through a plugin registry, size- and count-limited
Storage DigitalOcean Spaces (S3-compatible); free-plan documents expire and are swept by a maintenance endpoint
Admin Users, subscriptions and per-generation cost tracking

Stack and shape

FastAPI (async, Python 3.11) + PostgreSQL through SQLAlchemy 2.0 and Alembic, Redis for rate limiting, Next.js 15 + React 19 for the frontend, Docker Compose for both. LLM access goes through a provider-agnostic layer (OpenAI, DeepSeek, Anthropic) resolved per plan and per task, so structure generation, content generation, rubric extraction and JSON repair can each run on a different model.

backend/app/
├── api/            # routers: auth · documents · payments · admin  (/api/v1)
├── core/
│   ├── document/   # pipeline (structure → content → contract → citations → assembly → gate)
│   ├── citations/  # candidate search, dedup, ranking, validation, cache
│   ├── llm/        # provider-agnostic layer + prompts
│   ├── attachments/# parser registry per file type
│   └── storage/    # S3-compatible provider
├── models/ schemas/ services/ middleware/
frontend/src/app/
├── (app)/dashboard/  # generate · documents · credits · account
├── (auth)/           # login · registro
└── admin/            # users · subscriptions · costs

Run it locally

Everything runs through make; the dev stack is Docker Compose (API, PostgreSQL, Redis).

make up-detached        # start the stack
make migrate            # apply migrations
make fe-dev             # Next.js dev server with hot reload
make dev                # both at once

make test               # pytest, excluding tests that call external APIs
make check              # ruff + mypy

The backend needs a .env; at minimum a database URL and a JWT secret. LLM, citation, Stripe and storage keys are optional in development — without them the app runs, but document generation stops at the first LLM call.

Documentation index · Setup · Architecture · API reference · Pipeline · Citations · Runbook · Troubleshooting · Referencia técnica en español


Academic honesty

Studymation is an assistance tool: the student accepts responsibility for the work before generating, the document is meant to be reviewed and edited, and the system refuses to fabricate the one thing that would be hardest to check — the sources.

About

SaaS para generacion de documentos con plantillas y fuentes universitarias con agentes de IA.

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages