> ## Documentation Index
> Fetch the complete documentation index at: https://aipkg.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Layer

> EasyAF setup, SQL Server Database Project schema definitions, entity code generation workflow, and the schema change process.

The AI•Pkg data layer uses EasyAF (easyaf.dev) to eliminate hand-written EF migrations and enforce the SQL Server Database Project as the authoritative schema source.

***

## EasyAF Overview

EasyAF provides:

<CardGroup cols={2}>
  <Card title="SQL Server DB Project" icon="database">
    The `.sqlproj` is the authoritative schema. No hand-written EF migrations.
  </Card>

  <Card title="Entity Generation" icon="code">
    EasyAF CLI reads the `.sqlproj` and generates EF Core 10 entity classes.
  </Card>

  <Card title="Repository Generation" icon="layer-group">
    Standard CRUD repository classes are generated, reducing boilerplate.
  </Card>

  <Card title="OData Restier" icon="lock">
    Used exclusively for the internal admin/management API surface. Not exposed publicly.
  </Card>
</CardGroup>

***

## Data Layer Projects

```
AI•Pkg.Server.Db/          (.sqlproj)
  Tables/
    Packages.sql
    PackageVersions.sql
    PackageOwners.sql
    Users.sql
    ApiKeys.sql
    Downloads.sql

AI•Pkg.Server.Data/        (generated by EasyAF)
  Entities/
    Package.cs            ← generated from Packages.sql
    PackageVersion.cs     ← generated from PackageVersions.sql
  Repositories/
    PackageRepository.cs  ← generated CRUD
  AIpkgDbContext.cs       ← generated EF Core DbContext
```

***

## Schema Definitions

### AI•Pkg Table Schema (from NuGetGallery)

| NuGetGallery source   | AI•Pkg table          | Changes                                                                                                                                        |
| --------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Packages`            | `Packages`            | Remove: `RequiresLicenseAcceptance`, `DevelopmentDependency`, `IsSymbolsPackage`. Add: `Capabilities`, `Targets`, `Permissions` (JSON columns) |
| `PackageVersions`     | `PackageVersions`     | Same as above; keep download count                                                                                                             |
| `PackageOwners`       | `PackageOwners`       | No change                                                                                                                                      |
| `Users`               | `Users`               | Keep; remove legacy OpenID fields                                                                                                              |
| `Credentials`         | `Credentials`         | Keep PBKDF2 API key structure                                                                                                                  |
| `PackageDependencies` | `PackageDependencies` | Add `Apms` column (JSON) instead of `TargetFramework`                                                                                          |
| `PackageTags`         | `PackageTags`         | No change                                                                                                                                      |
| `PackageHistories`    | `PackageHistories`    | No change                                                                                                                                      |
| `PackageRenames`      | *(drop)*              | Not needed                                                                                                                                     |
| `SymbolPackages`      | *(drop)*              | Not applicable                                                                                                                                 |

### New JSON Columns

Three new JSON columns on `Packages` / `PackageVersions`:

| Column         | JSON Type  | Example                                  |
| -------------- | ---------- | ---------------------------------------- |
| `Capabilities` | `string[]` | `["skill","command"]`                    |
| `Targets`      | `string[]` | `["claude-code","cursor"]`               |
| `Permissions`  | `string[]` | `["filesystem:read","network:outbound"]` |

These are stored as `nvarchar(max)` JSON columns and indexed via computed columns where needed for Azure AI Search sync.

***

## Schema Change Workflow

<Steps>
  <Step title="Edit SQL files">
    Edit `.sql` files in `AI•Pkg.Server.Db/`.
  </Step>

  <Step title="Regenerate entities">
    Run EasyAF codegen to regenerate entities in `AI•Pkg.Server.Data/`.
  </Step>

  <Step title="Publish DB project">
    Publish the `.sqlproj` to the target database (generates and runs migration scripts).
  </Step>

  <Step title="Commit changes">
    Commit both `.sqlproj` changes and regenerated entity files.
  </Step>
</Steps>

***

## EasyAF Code Generation

Run EasyAF CLI against `AI•Pkg.Server.Db/` to generate:

```bash theme={null}
easyaf generate --project AI•Pkg.Server.Db --output AI•Pkg.Server.Data
```

This produces:

* `AI•Pkg.Server.Data/Entities/*.cs` — one file per table, strongly typed
* `AI•Pkg.Server.Data/Repositories/*.cs` — standard CRUD repositories
* `AI•Pkg.Server.Data/AIpkgDbContext.cs` — EF Core `DbContext` with all `DbSet<T>` properties

Generated files are committed to the repo. The `.gitignore` does **not** exclude them — they are the contract between the DB schema and the application code.

***

## Admin API (OData Restier)

EasyAF's OData Restier integration is used exclusively for the internal admin/management API surface. It is:

* **Not** on the public surface (no public routes)
* **Not** in scope for the public [Registry API spec](../specs/09-registry-api)
* Accessible only to admin-role authenticated users via internal tooling

Restier auto-generates an OData feed from `AIpkgDbContext`, providing a fully explorable admin API without hand-written controllers.
