Swadhin Biswas feat(api): add runner, analytics, packages, and security services · 3/6/2026
28f7954
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* Package Registry Schema
* Supports npm, Docker/OCI, Maven, PyPI, RubyGems, NuGet package types
*/
import { relations } from "drizzle-orm";
import {
boolean,
index,
integer,
jsonb,
pgTable,
text,
timestamp,
uniqueIndex,
} from "drizzle-orm/pg-core";
import { organizations } from "./organizations";
import { repositories } from "./repositories";
import { users } from "./users";
// ============================================================================
// PACKAGES
// ============================================================================
export const packages = pgTable(
"packages",
{
id: text("id").primaryKey(),
/** Organization-scoped or user-scoped */
organizationId: text("organization_id").references(() => organizations.id, {
onDelete: "cascade",
}),
/** Link to a repository (optional — packages can be org-level) */
repositoryId: text("repository_id").references(() => repositories.id, {
onDelete: "set null",
}),
/** Package type: npm, docker, maven, pypi, rubygems, nuget, generic */
type: text("type").notNull(),
/** Scoped package name e.g. "@scope/name" or "my-image" */
name: text("name").notNull(),
/** Human-readable description */
description: text("description"),
/** Public or private */
visibility: text("visibility").default("private").notNull(), // public, private
/** Total downloads across all versions */
downloadCount: integer("download_count").default(0).notNull(),
/** Who published the first version */
createdById: text("created_by_id").references(() => users.id),
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow(),
},
(table) => ({
uniqueName: uniqueIndex("pkg_org_type_name_idx").on(
table.organizationId,
table.type,
table.name,
),
typeIdx: index("pkg_type_idx").on(table.type),
}),
);
// ============================================================================
// PACKAGE VERSIONS
// ============================================================================
export const packageVersions = pgTable(
"package_versions",
{
id: text("id").primaryKey(),
packageId: text("package_id")
.notNull()
.references(() => packages.id, { onDelete: "cascade" }),
/** Semantic version string */
version: text("version").notNull(),
/** Content digest / hash (sha256) */
digest: text("digest"),
/** Size in bytes */
sizeBytes: integer("size_bytes"),
/** Storage path/key in the storage adapter */
storagePath: text("storage_path").notNull(),
/** Package-type-specific metadata (e.g. npm package.json fields) */
metadata: jsonb("metadata"),
/** Tag labels: latest, next, beta, etc. */
tags: jsonb("tags").$type<string[]>().default([]),
/** Associated git tag or commit SHA */
gitRef: text("git_ref"),
/** Who published this version */
publishedById: text("published_by_id").references(() => users.id),
/** Download count for this specific version */
downloadCount: integer("download_count").default(0).notNull(),
/** Whether this version is yanked/deprecated */
yanked: boolean("yanked").default(false),
createdAt: timestamp("created_at").notNull().defaultNow(),
},
(table) => ({
uniqueVersion: uniqueIndex("pkg_version_idx").on(
table.packageId,
table.version,
),
digestIdx: index("pkg_digest_idx").on(table.digest),
}),
);
// ============================================================================
// RELATIONS
// ============================================================================
export const packagesRelations = relations(packages, ({ one, many }) => ({
organization: one(organizations, {
fields: [packages.organizationId],
references: [organizations.id],
}),
repository: one(repositories, {
fields: [packages.repositoryId],
references: [repositories.id],
}),
createdBy: one(users, {
fields: [packages.createdById],
references: [users.id],
}),
versions: many(packageVersions),
}));
export const packageVersionsRelations = relations(
packageVersions,
({ one }) => ({
package: one(packages, {
fields: [packageVersions.packageId],
references: [packages.id],
}),
publishedBy: one(users, {
fields: [packageVersions.publishedById],
references: [users.id],
}),
}),
);
// ============================================================================
// TYPES
// ============================================================================
export type Package = typeof packages.$inferSelect;
export type NewPackage = typeof packages.$inferInsert;
export type PackageVersion = typeof packageVersions.$inferSelect;
export type NewPackageVersion = typeof packageVersions.$inferInsert;