AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Codebase Guide

skill-deadlymind-nanolama-codebase-guide · by Deadlymind

The master map for building a feature end to end on this Django 5.2 / DRF 3.16 + Next.js stack — the model to serializer to ViewSet to urls/router to tests pipeline, every step tenant-scoped by the entreprise FK and gated by {resource}_{action} RBAC. Use when starting a new feature, adding an endpoint or app, onboarding to the conventions, asking "how is a feature built here" or "where does this…

No reviews yet
0 installs
24 views
0.0% view→install

Install

$ agentstack add skill-deadlymind-nanolama-codebase-guide

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-deadlymind-nanolama-codebase-guide)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
24d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Codebase Guide? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Codebase guide (how a feature is built end to end)

When to use

Starting any new feature, endpoint, or app, or checking that a change follows the house conventions. This is the map; the specialist skills are the terrain. Read it first, then dive into the layer you are touching.

Pattern

Every business feature flows through the same five files, in order: models.py (tenant FK) → serializers.py (field shape) → views.py/ViewSet (scope + RBAC) → urls.py/router (route name) → tests.py (isolation test).

Two invariants ride along every step and are non-negotiable on a new endpoint:

  1. Tenant scope — the row is filtered/stamped by the current entreprise

(fail-closed), never trusted from the client (see multi-tenancy).

  1. RBAC gate — access is gated by a {resource}_{action} permission

(see rbac-permissions).

A worked example, one file per step (migration follows the model — see migrations):

# invoices/models.py
class Invoice(models.Model):
    entreprise = models.ForeignKey(               # rename to your tenant FK
        "tenants.Entreprise", on_delete=models.CASCADE,
        null=False, related_name="invoices")
    number = models.CharField(max_length=32)
    class Meta:
        indexes = [models.Index(fields=["entreprise"])]  # every filter hits it

# invoices/serializers.py  (see drf-api)
class InvoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invoice
        fields = ["id", "number", "entreprise"]
        read_only_fields = ["entreprise"]         # server stamps it, not the client

# invoices/views.py  — both invariants enforced here
class InvoiceViewSet(TenantScopedViewSet):        # get_queryset filters by tenant
    serializer_class = InvoiceSerializer
    queryset = Invoice.objects.all()
    permission_classes = [HasResourcePermission]  # gates by invoice_{action}
    perm_base = "invoice"                         # matches rbac-permissions -> invoice_read/create/...

# invoices/urls.py  — basename gives reversible route names; mount under /api/
router = DefaultRouter()
router.register("invoices", InvoiceViewSet, basename="invoice")

# invoices/tests.py  — the mandatory tenant-isolation test (see write-tests)
def test_tenant_isolation(self):
    self.client.cookies = self.user_a_cookies     # user A must NOT see B's invoice
    resp = self.client.get(f"/api/invoices/{self.invoice_b.id}/")
    assert resp.status_code == 404                # scoped queryset -> 404, not 403

Conventions on every change:

  • New endpoint ⇒ tenant filter and RBAC permission, both. A filter with no gate

leaks within the tenant; a gate with no filter leaks across tenants.

  • One app per bounded resource; keep models / serializers / views / urls / tests

split as above rather than one mega-file.

  • Server owns the tenant: read_only_fields on the FK, stamped in perform_create.

Stamp the audit trail in the same override — perform_create sets created_by (and updated_by) alongside the tenant, perform_update sets updated_by — from the request user, never the client. Newcomers wire the tenant and forget the who.

  • Tests include the isolation case for every scoped resource — it is the one test

reviewers block a PR for missing.

Adapt to your repo

Rename Entreprise/entreprise and the accessor (user.entreprise_id) to your tenant model. Adjust the resource string and permission class to your RBAC helper's names. Confirm your project urls.py mounts app routers under a stable prefix (/api/). Frontend features mirror this on the Next.js side — see nextjs-module.

Gotchas

  • Skipping the router basename breaks reverse() and DRF's HyperlinkedIdentityField.
  • Model.objects.get(pk=...) inside a view bypasses tenant scoping — always go

through the scoped get_queryset() / get_object().

  • Custom @action methods do not inherit the RBAC check automatically — gate each one.
  • A migration that adds a null=False tenant FK to a populated table needs a default

or a data migration (see migrations).

  • Business rows are soft-deleted, not hard-DELETEd. Override destroy() to set a

flag (archived_at / is_deleted) instead of removing the row, and exclude flagged rows from the default get_queryset() so they drop out of lists and 404 on detail while staying recoverable. A real DELETE loses the audit trail and breaks FKs.

See also

  • multi-tenancy
  • drf-api
  • rbac-permissions
  • migrations
  • write-tests

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.