Skip to content

Deployment update#222

Open
Rufat00 wants to merge 4 commits intodevfrom
deployment_update
Open

Deployment update#222
Rufat00 wants to merge 4 commits intodevfrom
deployment_update

Conversation

@Rufat00
Copy link
Collaborator

@Rufat00 Rufat00 commented Feb 12, 2026

Why

A lot of unused code and libraries.

What

Deleting them all

Satisfies

https://linear.app/acmutsa/issue/HK-222/remove-unnecessary-packages
#215

Summary by CodeRabbit

  • Chores

    • Removed backup service, migration utilities, and email functionality
    • Removed API layer and related infrastructure
    • Simplified runtime configurations across application
    • Updated environment variable naming and dependency structure
  • Refactor

    • Extracted shared form options to centralized configuration module
    • Simplified timezone handling using configuration values
  • Configuration & Infrastructure

    • Added Docker containerization setup
    • Introduced deployment configuration module
    • Updated database schema and environment setup

@coderabbitai
Copy link

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Large-scale refactoring removing tRPC infrastructure, email services, edge runtime declarations, and two monorepo applications (backups, infrastructure-migrator). Dependencies reorganized, Cloudflare-specific features replaced with config-based values, and Docker containerization added for web deployment.

Changes

Cohort / File(s) Summary
Application Removal
apps/backups/*, apps/infrastructure-migrator/*
Complete deletion of backups service (Wrangler-based backup orchestration with S3 uploads) and infrastructure-migrator utilities (Postgres-to-SQLite migration driver). Removes package manifests, TypeScript configs, environment setup, and database schema definitions.
tRPC Infrastructure Removal
apps/web/src/server/api/*, apps/web/src/trpc/*, apps/web/src/app/api/trpc/[trpc]/route.ts
Eliminates tRPC server setup (context, procedures, router wiring), client-side React integration (TRPCReactProvider, query-client), and API route handlers. Removes POST/GET tRPC endpoints and Clerk-based authentication middleware within tRPC procedures.
Email Service Removal
apps/web/src/lib/utils/server/ses.ts, apps/web/src/emails/RegistrationSuccessEmail.tsx, apps/web/src/lib/utils/server/types.ts
Deletes SES email client, RegistrationSuccessEmail component (react-email based), and DefaultEmailTemplateProps type. Removes SMTP sending logic and related environment variables (AWS_SES_*).
Edge Runtime Declarations
apps/web/src/app/**/*, apps/web/src/components/**/*
Removes export const runtime = "edge" from ~35 files across pages, layouts, and components. Shifts default runtime from Cloudflare Edge to Node.js across admin, dashboard, schedule, and public routes.
Cloudflare Context to Config Migration
apps/web/src/app/admin/page.tsx, apps/web/src/app/dash/schedule/page.tsx, apps/web/src/components/events/admin/EventDetails.tsx, apps/web/src/components/schedule/Day.tsx, apps/web/src/app/schedule/page.tsx
Replaces runtime timezone extraction via getRequestContext() and cf.timezone with static config-based c.hackathonTimezone. Removes request header imports and dependencies on Cloudflare request context.
Dashboard & Tickets Refactoring
apps/web/src/app/dash/layout.tsx, apps/web/src/app/dash/tickets/layout.tsx, apps/web/src/app/dash/tickets/new/page.tsx, apps/web/src/app/dash/tickets/page.tsx, apps/web/src/components/dash/tickets/TicketList.tsx
Removes TRPCReactProvider wrapper, eliminates TicketsLayout two-pane composition, deletes ticket creation page with TRPC mutation, and removes TicketList dummy-data component. Simplifies dashboard structure.
Admin Users & Role Management
apps/web/src/app/admin/users/[slug]/page.tsx, apps/web/src/components/admin/users/UpdateRoleDialog.tsx
Adds roles database fetch and prop propagation to UpdateRoleDialog; converts component from async to sync by accepting roles via props instead of querying database internally.
Package Dependency Reorganization
apps/web/package.json, packages/config/package.json
Moves type definitions and build tools (@types/*, autoprefixer, dotenv, jiti, postcss, tailwindcss, typescript) from dependencies to devDependencies. Removes TRPC packages, query-client, SES SDK, animation libraries (gsap, framer-motion), and database drivers (pg, postgres).
Configuration & Constants Extraction
packages/config/constants.ts, packages/config/hackkit.config.ts, packages/config/hackckit.deploy.ts
Creates new constants.ts with form option arrays (schools, majors, dietary restrictions, etc.). Refactors hackkit.config.ts to import constants and removes in-file definitions. Introduces new deploy configuration aggregating AWS, Clerk, Discord, and bucket settings.
Environment Variable Consolidation
.env.example, apps/web/src/env.ts, apps/web/src/lib/utils/server/redis.ts
Comments out BACKUP_* and POSTGRES_* variables in .env.example; removes AWS SES and HK_ENV from env validation; replaces HK_ENV usage with NODE_ENV in Redis key prefix and turbo.json.
Infrastructure & Component Cleanup
Dockerfile, apps/web/.gitignore, apps/web/next.config.mjs, apps/web/src/middleware.ts, apps/web/src/components/Restricted.tsx, apps/web/src/lib/utils/client/zfetch.ts
Adds multi-stage Dockerfile for Node.js/Next.js with pnpm; updates .gitignore to track certificates/; removes Cloudflare dev setup from next.config; removes TRPC route from middleware matcher; updates Restricted component return logic; deletes zfetch HTTP utility module.
Router & Procedure Cleanup
apps/web/src/server/api/root.ts, apps/web/src/server/api/routers/post.ts, apps/web/src/server/api/routers/tickets.ts, apps/web/src/app/admin/points/page.tsx, apps/web/src/app/admin/toggles/tickets/page.tsx, apps/web/src/app/dash/tickets/page.tsx
Removes appRouter, createCaller exports; deletes postRouter and ticketsRouter (including create mutation logic and chat integration); removes stub admin pages (points, toggles/tickets, tickets page).
Script & Build Configuration
package.json, turbo.json
Adds start and db:seed scripts; removes tunnel script; introduces start task in turbo with caching and build dependency; replaces HK_ENV with NODE_ENV in globalEnv.
Miscellaneous Deletions
apps/web/src/app/admin/check-in/page.tsx, apps/web/src/app/admin/events/new/page.tsx, apps/web/src/app/api/upload/pfp/route.ts, apps/web/src/app/api/upload/resume/register/route.ts, apps/web/src/app/api/upload/resume/view/route.ts, apps/web/src/components/admin/landing/Overview.tsx, apps/web/src/components/admin/users/ServerSections.tsx, apps/web/src/components/dash/shared/ProfileButton.tsx, apps/web/src/components/shared/*
Removes runtime exports and minor page/component stubs; cleans up shared navbar components and upload route runtime declarations.

Sequence Diagram(s)

No sequence diagrams generated. Changes are primarily deletions, refactoring (moving logic to config), and dependency reorganization without introducing new multi-component control flows requiring visualization.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 The warren once thrived with tRPC streams,
Edge runtimes swift, like hackathon dreams,
But hark! We've trimmed the excess away,
Config and Drizzle shall guide us today,
The monorepo breathes lighter—hooray! 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 4
❌ Failed checks (3 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Multiple out-of-scope changes detected: entire apps/backups and apps/infrastructure-migrator directories removed; Cloudflare-specific request context replaced with config-based timezone across many files; removed email/SES functionality unrelated to package cleanup; TRPC API layer completely removed; removed React Query setup. These changes exceed the stated objective of removing unnecessary packages. Separate architectural changes (Cloudflare removal, TRPC removal, email removal) into distinct PRs. Keep this PR focused solely on package/dependency cleanup and moving dev-time dependencies appropriately.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (55 files):

⚔️ .env.example (content)
⚔️ apps/web/.gitignore (content)
⚔️ apps/web/next.config.mjs (content)
⚔️ apps/web/package.json (content)
⚔️ apps/web/src/app/admin/check-in/page.tsx (content)
⚔️ apps/web/src/app/admin/events/new/page.tsx (content)
⚔️ apps/web/src/app/admin/layout.tsx (content)
⚔️ apps/web/src/app/admin/page.tsx (content)
⚔️ apps/web/src/app/admin/scanner/[id]/page.tsx (content)
⚔️ apps/web/src/app/admin/toggles/landing/page.tsx (content)
⚔️ apps/web/src/app/admin/toggles/registration/page.tsx (content)
⚔️ apps/web/src/app/admin/users/[slug]/page.tsx (content)
⚔️ apps/web/src/app/admin/users/page.tsx (content)
⚔️ apps/web/src/app/api/admin/export/route.ts (content)
⚔️ apps/web/src/app/api/upload/pfp/route.ts (content)
⚔️ apps/web/src/app/api/upload/resume/register/route.ts (content)
⚔️ apps/web/src/app/api/upload/resume/view/route.ts (content)
⚔️ apps/web/src/app/dash/layout.tsx (content)
⚔️ apps/web/src/app/dash/page.tsx (content)
⚔️ apps/web/src/app/dash/pass/page.tsx (content)
⚔️ apps/web/src/app/dash/schedule/page.tsx (content)
⚔️ apps/web/src/app/discord-verify/linked/page.tsx (content)
⚔️ apps/web/src/app/discord-verify/page.tsx (content)
⚔️ apps/web/src/app/i/approval/page.tsx (content)
⚔️ apps/web/src/app/layout.tsx (content)
⚔️ apps/web/src/app/not-found.tsx (content)
⚔️ apps/web/src/app/page.tsx (content)
⚔️ apps/web/src/app/register/page.tsx (content)
⚔️ apps/web/src/app/rsvp/page.tsx (content)
⚔️ apps/web/src/app/schedule/[id]/page.tsx (content)
⚔️ apps/web/src/app/schedule/page.tsx (content)
⚔️ apps/web/src/app/suspended/page.tsx (content)
⚔️ apps/web/src/app/user/[tag]/page.tsx (content)
⚔️ apps/web/src/components/admin/landing/Overview.tsx (content)
⚔️ apps/web/src/components/admin/users/ServerSections.tsx (content)
⚔️ apps/web/src/components/admin/users/UpdateRoleDialog.tsx (content)
⚔️ apps/web/src/components/dash/shared/ProfileButton.tsx (content)
⚔️ apps/web/src/components/events/admin/EditEventForm.tsx (content)
⚔️ apps/web/src/components/events/admin/EventDetails.tsx (content)
⚔️ apps/web/src/components/schedule/Day.tsx (content)
⚔️ apps/web/src/components/shared/MobileNavBarLinks.tsx (content)
⚔️ apps/web/src/components/shared/NavBarLinksGrouper.tsx (content)
⚔️ apps/web/src/components/shared/Navbar.tsx (content)
⚔️ apps/web/src/components/shared/ProfileButton.tsx (content)
⚔️ apps/web/src/env.ts (content)
⚔️ apps/web/src/lib/utils/server/redis.ts (content)
⚔️ apps/web/src/lib/utils/server/types.ts (content)
⚔️ apps/web/src/middleware.ts (content)
⚔️ package.json (content)
⚔️ packages/config/hackkit.config.ts (content)
⚔️ packages/config/package.json (content)
⚔️ packages/db/index.ts (content)
⚔️ packages/db/schema.ts (content)
⚔️ pnpm-lock.yaml (content)
⚔️ turbo.json (content)

These conflicts must be resolved before merging into dev.
Resolve conflicts locally and push changes to this branch.
Title check ❓ Inconclusive The PR title 'Deployment update' is vague and does not clearly convey the main change of removing unnecessary packages and dependencies. Consider using a more descriptive title like 'Remove unnecessary packages and move dependencies to devDependencies' to better reflect the primary objective.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR successfully addresses HK-222 by removing unused packages and moving dependencies to devDependencies. Package.json modifications demonstrate removal of AWS SDK, TRPC, UI libraries, and tooling from dependencies, with appropriate entries moved to devDependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch deployment_update
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch deployment_update
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
apps/web/src/components/admin/users/UpdateRoleDialog.tsx (1)

89-94: ⚠️ Potential issue | 🔴 Critical

Bug: Both badges display the current role name instead of showing the transition.

The footer is intended to show a visual "old role → new role" transition, but Line 93 renders currentRoleName again instead of the newly selected role's name. The second <Badge> should display the name of roleToSet.

🐛 Proposed fix
 				{roleToSet !== currentRoleId ? (
 					<div className="flex h-full w-full items-center justify-center gap-x-2 self-end sm:justify-start">
 						<Badge>{currentRoleName}</Badge>
 						<span>&rarr;</span>
-						<Badge>{currentRoleName}</Badge>
+						<Badge>
+							{titleCase(
+								roles.find((r) => r.id === roleToSet)?.name.replace("_", " ") || "",
+							)}
+						</Badge>
 					</div>
 				) : null}
apps/web/src/app/admin/users/[slug]/page.tsx (1)

149-156: ⚠️ Potential issue | 🟠 Major

Mobile UpdateRoleDialog is not wrapped in <Restricted> unlike the desktop version.

The desktop path (Lines 80–92) gates UpdateRoleDialog behind a <Restricted> permission check for CHANGE_USER_ROLES, but the mobile dropdown renders it unconditionally. This appears to be a pre-existing issue, but since both paths are being touched in this PR it would be a good time to fix it.

🛡️ Proposed fix — wrap the mobile role dialog in Restricted
-						<div className="cursor-pointer rounded-sm px-2 py-1.5 text-center text-sm hover:bg-accent">
-							<UpdateRoleDialog
-								name={`${subject.firstName} ${subject.lastName}`}
-								currentRoleId={subject.role_id}
-								userID={subject.clerkID}
-								roles={roles}
-							/>
-						</div>
+						<Restricted
+							user={admin}
+							permissions={PermissionType.CHANGE_USER_ROLES}
+							targetRolePosition={subject.role.position}
+							position="higher"
+						>
+							<div className="cursor-pointer rounded-sm px-2 py-1.5 text-center text-sm hover:bg-accent">
+								<UpdateRoleDialog
+									name={`${subject.firstName} ${subject.lastName}`}
+									currentRoleId={subject.role_id}
+									userID={subject.clerkID}
+									roles={roles}
+								/>
+							</div>
+						</Restricted>
packages/db/schema.ts (1)

61-72: ⚠️ Potential issue | 🟡 Minor

chatType is now dead code.

The only consumer of chatType was the chats table definition, which is now commented out. This custom type should be removed along with the commented-out schema.

apps/web/src/app/dash/layout.tsx (1)

20-25: ⚠️ Potential issue | 🟠 Major

Duplicate getUser call — fetch once and reuse.

getUser(clerkUser.id) is called on line 20 and again on line 24 with the same argument. The second call is redundant since the first already guards against undefined. Store the result once:

🔧 Proposed fix
-	if (!clerkUser || (await getUser(clerkUser.id)) == undefined) {
+	if (!clerkUser) {
 		return redirect("/register");
 	}
 
 	const user = await getUser(clerkUser.id);
 	if (!user) return redirect("/register");
🤖 Fix all issues with AI agents
In `@apps/web/src/components/admin/users/UpdateRoleDialog.tsx`:
- Around line 42-44: The currentRoleName computation (and the similar code
around the role label rendering) uses .replace("_", " ") which only replaces the
first underscore; change those to use either .replaceAll("_", " ") or
.replace(/_/g, " ") so all underscores in the role name (e.g.,
"super_admin_user") are replaced; update the expression where currentRoleName is
set (roles.find((r) => r.id === currentRoleId)?.name.replace(...)) and the
analogous code used later (the role label/rendering block) to use the global
replace variant.

In `@apps/web/src/components/Restricted.tsx`:
- Around line 26-43: The position checks in the Restricted component are
inverted: replace the current truthy/inequality checks with explicit comparisons
to compareUserPosition(user, targetRolePosition) so "higher" uses === 1, "lower"
uses === -1, and "equal" uses === 0 (locate the checks using the position
variable and compareUserPosition call in the Restricted component and update
those three conditionals to the explicit numeric comparisons so children render
only for the correct authorization cases).

In `@Dockerfile`:
- Around line 40-43: The Next.js build isn't producing .next/standalone because
the Next config lacks output: "standalone"; open next.config.js and add the
property output: "standalone" to the exported nextConfig (e.g., in the
nextConfig object or default export) so the build generates .next/standalone and
.next/static that the Dockerfile's COPY --from=builder commands (referencing
.next/standalone and .next/static) can use.
- Around line 12-14: The Dockerfile's deps stage only copies root
package.json/pnpm-lock and runs RUN pnpm install --frozen-lockfile, but pnpm
needs all workspace package.json manifests to resolve workspace packages; update
the COPY step (the COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* .npmrc*
./ line) to also copy each workspace manifest (e.g., apps/web/package.json,
apps/bot/package.json, packages/config/package.json, packages/db/package.json,
packages/devtunnel/package.json, packages/tsconfig/package.json) into the build
context before RUN pnpm install, or alternatively replace this approach with a
turborepo prune flow (e.g., using turbo prune --scope=web --docker to produce a
pruned lockfile) so RUN pnpm install --frozen-lockfile can succeed.

In `@packages/config/constants.ts`:
- Line 444: The string constant option "Cinematography/Film/Vide Production" in
packages/config/constants.ts contains a typo; update that option value to
"Cinematography/Film/Video Production" wherever it's defined (search for the
exact string "Cinematography/Film/Vide Production" in the file and replace it
with "Cinematography/Film/Video Production") so the user-facing form selection
shows the correct "Video" spelling.

In `@packages/config/hackckit.deploy.ts`:
- Around line 1-54: The file name contains a typo: rename the file from
hackckit.deploy.ts to hackkit.deploy.ts and update any imports that reference it
so modules continue to import the deployConfig export; specifically ensure
references to the exported symbol deployConfig (from this file) are updated to
the new filename and verify consistency with the sibling hackkit.config.ts.

In `@packages/db/index.ts`:
- Line 5: The shared package's top-level import "server-only" in
packages/db/index.ts breaks non-RSC Node scripts like
packages/db/seeders/seed.ts; remove that import from the package entrypoint and
either (A) move the import into the consuming app (e.g., add import
"server-only" to the server entry in apps/web where DB is used in RSC), or (B)
add a separate server-only entrypoint (e.g., packages/db/server.ts) that imports
"server-only" and re-exports the same exports as packages/db/index.ts, then
update RSC consumers to import from that server-only entrypoint while seed
scripts continue to import the plain packages/db export. Ensure all references
to the original index remain valid or update them to the new server entry where
RSC-only behavior is required.

In `@turbo.json`:
- Around line 40-44: The "start" task in turbo.json is marked as persistent
(persistent: true) but also has caching enabled (cache: true), which is invalid
for long-running tasks; update the "start" task configuration to set cache to
false so Turborepo doesn't attempt to cache a persistent task — locate the
"start" task entry and change its "cache" value from true to false while leaving
"persistent": true and "dependsOn": ["^build"] as-is.
🧹 Nitpick comments (5)
packages/db/schema.ts (1)

74-82: Prefer deleting dead code over commenting it out.

These ~100 lines of commented-out schema definitions (ticket/chat tables, relations, enums) add noise. Git history preserves the old code if it's ever needed again. Consider removing the comments entirely.

Also applies to: 333-433

packages/db/index.ts (1)

9-12: Non-null assertion on env vars with no validation.

process.env.TURSO_DATABASE_URL! will silently pass undefined to the client if the env var is missing, likely causing a cryptic runtime error. This is pre-existing code, but since you're touching this file, consider adding a startup check or using a schema validator (e.g., Zod) for env vars.

Dockerfile (1)

49-50: HOSTNAME should use the ENV key-value form consistently.

Minor: HOSTNAME="0.0.0.0" works but the quotes are unnecessary in Dockerfile ENV directives (unlike lines 32, 35, 49 which don't use quotes). This is purely cosmetic — no functional issue.

packages/config/hackckit.deploy.ts (1)

1-54: Silent empty-string fallbacks for secrets can mask misconfiguration.

Every secret (AWS credentials, Clerk secret key, Discord bot token, etc.) falls back to "" if the env var is missing. This means the app will start successfully but fail at runtime with opaque errors (e.g., unauthorized API calls). Consider throwing at startup if required secrets are absent, or at minimum use a schema validator like @t3-oss/env-nextjs (already a dependency) to enforce required variables.

packages/config/hackkit.config.ts (1)

136-137: Pre-existing bug: Sunday is outside the days object.

Not introduced in this PR, but Sunday (line 137) sits at the top level of c rather than inside days alongside Saturday. This is likely unintentional.

	days: {
		Saturday: new Date(2023, 6, 15),
	},
	Sunday: new Date(2023, 6, 16),  // ← should be inside `days`

Comment on lines 42 to 44
const currentRoleName = titleCase(
roles.find((r) => r.id === currentRoleId)?.name.replace("_", " ") || "",
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

.replace("_", " ") only replaces the first underscore.

If any role name contains multiple underscores (e.g., "super_admin_user"), only the first will be replaced. Consider using replaceAll("_", " ") or a regex for a global replace.

Also applies to: 77-83

🤖 Prompt for AI Agents
In `@apps/web/src/components/admin/users/UpdateRoleDialog.tsx` around lines 42 -
44, The currentRoleName computation (and the similar code around the role label
rendering) uses .replace("_", " ") which only replaces the first underscore;
change those to use either .replaceAll("_", " ") or .replace(/_/g, " ") so all
underscores in the role name (e.g., "super_admin_user") are replaced; update the
expression where currentRoleName is set (roles.find((r) => r.id ===
currentRoleId)?.name.replace(...)) and the analogous code used later (the role
label/rendering block) to use the global replace variant.

Comment on lines 26 to 43
if (
position === "higher" &&
!compareUserPosition(user, targetRolePosition)
compareUserPosition(user, targetRolePosition)
) {
return <></>;
return <>{children}</>;
}
if (
position === "lower" &&
compareUserPosition(user, targetRolePosition) !== -1
) {
return <></>;
return <>{children}</>;
}
if (
position === "equal" &&
compareUserPosition(user, targetRolePosition) !== 0
) {
return <></>;
return <>{children}</>;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: All three position checks have inverted or incorrect logic.

Based on compareUserPosition returning 1 (higher), 0 (equal), or -1 (lower):

  • Line 28: compareUserPosition(...) is truthy for both 1 and -1, so position === "higher" also renders children when the user is lower. Should be === 1.
  • Line 34: !== -1 renders children when the user is higher or equal — the opposite of "lower". Should be === -1.
  • Line 40: !== 0 renders children when the user is not equal — the opposite of "equal". Should be === 0.

This is an authorization/access-control bug: users who should be restricted will see content, and users who should see content will be blocked.

🐛 Proposed fix
 	if (targetRolePosition !== undefined) {
 		if (
 			position === "higher" &&
-			compareUserPosition(user, targetRolePosition)
+			compareUserPosition(user, targetRolePosition) === 1
 		) {
 			return <>{children}</>;
 		}
 		if (
 			position === "lower" &&
-			compareUserPosition(user, targetRolePosition) !== -1
+			compareUserPosition(user, targetRolePosition) === -1
 		) {
 			return <>{children}</>;
 		}
 		if (
 			position === "equal" &&
-			compareUserPosition(user, targetRolePosition) !== 0
+			compareUserPosition(user, targetRolePosition) === 0
 		) {
 			return <>{children}</>;
 		}
 
 		return <></>;
 	}
🤖 Prompt for AI Agents
In `@apps/web/src/components/Restricted.tsx` around lines 26 - 43, The position
checks in the Restricted component are inverted: replace the current
truthy/inequality checks with explicit comparisons to compareUserPosition(user,
targetRolePosition) so "higher" uses === 1, "lower" uses === -1, and "equal"
uses === 0 (locate the checks using the position variable and
compareUserPosition call in the Restricted component and update those three
conditionals to the explicit numeric comparisons so children render only for the
correct authorization cases).

Dockerfile Outdated
Comment on lines 12 to 14
# Copy workspace manifests so pnpm can install only necessary packages
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* .npmrc* ./
RUN pnpm install --frozen-lockfile
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find all package.json files to understand the monorepo structure
fd package.json --max-depth 3 --type f

Repository: acmutsa/HackKit

Length of output: 232


🏁 Script executed:

# Check the Dockerfile structure, particularly around lines 12-14
fd Dockerfile --type f | head -5

Repository: acmutsa/HackKit

Length of output: 69


🏁 Script executed:

cat -n Dockerfile

Repository: acmutsa/HackKit

Length of output: 1775


Monorepo workspace manifests are missing — pnpm install will fail.

Only root-level package.json and lockfile are copied in the deps stage, but pnpm install --frozen-lockfile requires all workspace package.json files (apps/web/package.json, apps/bot/package.json, packages/config/package.json, packages/db/package.json, packages/devtunnel/package.json, packages/tsconfig/package.json) to resolve workspace dependencies. Without them, install fails because the lockfile references workspace packages that don't exist in the build context.

Copy all workspace package.json files before running install:

Proposed fix
 # Copy workspace manifests so pnpm can install only necessary packages
 COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* .npmrc* ./
+COPY apps/web/package.json ./apps/web/package.json
+COPY apps/bot/package.json ./apps/bot/package.json
+COPY packages/config/package.json ./packages/config/package.json
+COPY packages/db/package.json ./packages/db/package.json
+COPY packages/devtunnel/package.json ./packages/devtunnel/package.json
+COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
 RUN pnpm install --frozen-lockfile

Alternatively, use turbo prune --scope=web --docker to generate an optimized pruned lockfile and workspace subset for Docker layer caching.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Copy workspace manifests so pnpm can install only necessary packages
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* .npmrc* ./
RUN pnpm install --frozen-lockfile
# Copy workspace manifests so pnpm can install only necessary packages
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml* .npmrc* ./
COPY apps/web/package.json ./apps/web/package.json
COPY apps/bot/package.json ./apps/bot/package.json
COPY packages/config/package.json ./packages/config/package.json
COPY packages/db/package.json ./packages/db/package.json
COPY packages/devtunnel/package.json ./packages/devtunnel/package.json
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
RUN pnpm install --frozen-lockfile
🤖 Prompt for AI Agents
In `@Dockerfile` around lines 12 - 14, The Dockerfile's deps stage only copies
root package.json/pnpm-lock and runs RUN pnpm install --frozen-lockfile, but
pnpm needs all workspace package.json manifests to resolve workspace packages;
update the COPY step (the COPY package.json pnpm-lock.yaml pnpm-workspace.yaml*
.npmrc* ./ line) to also copy each workspace manifest (e.g.,
apps/web/package.json, apps/bot/package.json, packages/config/package.json,
packages/db/package.json, packages/devtunnel/package.json,
packages/tsconfig/package.json) into the build context before RUN pnpm install,
or alternatively replace this approach with a turborepo prune flow (e.g., using
turbo prune --scope=web --docker to produce a pruned lockfile) so RUN pnpm
install --frozen-lockfile can succeed.

Dockerfile Outdated
Comment on lines 40 to 43
# Copy public and standalone output from the workspace app
COPY --from=builder /app/apps/web/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/web/.next/static ./.next/static
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find next.config files and check for standalone output configuration
fd "next\.config" --type f -x cat {}

Repository: acmutsa/HackKit

Length of output: 711


Add output: "standalone" to the Next.js configuration.

The Dockerfile copies from .next/standalone and .next/static (lines 40-43), but the Next.js config does not include output: "standalone". Without this setting, these directories will not be generated during the build, causing the COPY commands to fail. Add the following to next.config.js:

const nextConfig = {
  output: "standalone",
  // ... rest of config
};
🤖 Prompt for AI Agents
In `@Dockerfile` around lines 40 - 43, The Next.js build isn't producing
.next/standalone because the Next config lacks output: "standalone"; open
next.config.js and add the property output: "standalone" to the exported
nextConfig (e.g., in the nextConfig object or default export) so the build
generates .next/standalone and .next/static that the Dockerfile's COPY
--from=builder commands (referencing .next/standalone and .next/static) can use.

"Cell/Cellular Biology",
"Chemical Engineering",
"Chemistry",
"Cinematography/Film/Vide Production",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo in major option: "Vide" → "Video".

"Cinematography/Film/Vide Production" is missing the o in "Video". This is user-facing text in form selections.

✏️ Proposed fix
-	"Cinematography/Film/Vide Production",
+	"Cinematography/Film/Video Production",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Cinematography/Film/Vide Production",
"Cinematography/Film/Video Production",
🤖 Prompt for AI Agents
In `@packages/config/constants.ts` at line 444, The string constant option
"Cinematography/Film/Vide Production" in packages/config/constants.ts contains a
typo; update that option value to "Cinematography/Film/Video Production"
wherever it's defined (search for the exact string "Cinematography/Film/Vide
Production" in the file and replace it with "Cinematography/Film/Video
Production") so the user-facing form selection shows the correct "Video"
spelling.

Comment on lines +1 to +54
export const deployConfig = {
providers: {
aws: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
region: process.env.AWS_REGION || "us-east-1",
},

// cloudflare: {
// pulumiApiToken: process.env.CLOUDFLARE_API_TOKEN || "",
// accountId: process.env.CLOUDFLARE_ACCOUNT_ID || "",
// r2: {
// bucketName: process.env.R2_BUCKET_NAME || "",
// accessKeyId: process.env.R2_ACCESS_KEY_ID || "",
// secretAccessKey: process.env.R2_SECRET_ACCESS_KEY || "",
// region: process.env.R2_BUCKET_REGION || "",
// },
// },

// vercel: {
// vercelToken: process.env.VERCEL_TOKEN || "",
// orgId: process.env.VERCEL_ORG_ID || "",
// projectId: process.env.VERCEL_PROJECT_ID || "",
// teamId: process.env.VERCEL_TEAM_ID || "",
// },

// netlify: {
// netlifyToken: process.env.NETLIFY_AUTH_TOKEN || "",
// siteId: process.env.NETLIFY_SITE_ID || "",
// },
},

clerk: {
publishableKey: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY || "",
secretKey: process.env.CLERK_SECRET_KEY || "",
webhookSecret: process.env.CLERK_WEBHOOK_SECRET || "",
},

discord: {
clientId: process.env.DISCORD_CLIENT_ID || "",
clientSecret: process.env.DISCORD_CLIENT_SECRET || "",
botToken: process.env.DISCORD_BOT_TOKEN || "",
publicKey: process.env.DISCORD_PUBLIC_KEY || "",
},

bucket: {
name: process.env.AWS_S3_BUCKET || "",
region: process.env.AWS_S3_REGION || process.env.AWS_REGION || "",
},

cron: {
backupSchedule: process.env.BACKUP_CRON_SCHEDULE || "",
},
} as const;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo in filename: hackckit.deploy.tshackkit.deploy.ts.

The filename has an extra c — "hackckit" instead of "hackkit". This will cause confusion and inconsistency with the sibling hackkit.config.ts.

🤖 Prompt for AI Agents
In `@packages/config/hackckit.deploy.ts` around lines 1 - 54, The file name
contains a typo: rename the file from hackckit.deploy.ts to hackkit.deploy.ts
and update any imports that reference it so modules continue to import the
deployConfig export; specifically ensure references to the exported symbol
deployConfig (from this file) are updated to the new filename and verify
consistency with the sibling hackkit.config.ts.

import { createClient as createClientEdge } from "@libsql/client/web";
import { createClient as createClientNodeServerless } from "@libsql/client";
import * as schema from "./schema";
import "server-only";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

server-only import may break the seed script.

The server-only package throws an error when imported outside of a React Server Components environment. Since packages/db/seeders/seed.ts imports from "../" (this file), running the seed script in a plain Node.js context (via esbuild-register) will likely fail with:

"This module cannot be imported from a Client Component module."

Consider moving the server-only guard to the consuming app layer (e.g., in apps/web) rather than in the shared db package, or provide a separate entry point for scripts that doesn't include this import.

#!/bin/bash
# Check how seed script is invoked and whether server-only would be an issue
rg -n "server-only" -g '!node_modules/**'
# Check package.json for seed script definition
fd -g 'package.json' --exec grep -l "seed" {} \;
🤖 Prompt for AI Agents
In `@packages/db/index.ts` at line 5, The shared package's top-level import
"server-only" in packages/db/index.ts breaks non-RSC Node scripts like
packages/db/seeders/seed.ts; remove that import from the package entrypoint and
either (A) move the import into the consuming app (e.g., add import
"server-only" to the server entry in apps/web where DB is used in RSC), or (B)
add a separate server-only entrypoint (e.g., packages/db/server.ts) that imports
"server-only" and re-exports the same exports as packages/db/index.ts, then
update RSC consumers to import from that server-only entrypoint while seed
scripts continue to import the plain packages/db export. Ensure all references
to the original index remain valid or update them to the new server entry where
RSC-only behavior is required.

Comment on lines +40 to +44
"start": {
"cache": true,
"persistent": true,
"dependsOn": ["^build"]
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

cache: true on a persistent task is likely incorrect.

Persistent tasks (like a long-running server started via start) never exit, so Turborepo cannot produce a meaningful cache entry. Turborepo typically warns about this combination. Set cache to false for persistent tasks.

Proposed fix
     "start": {
-      "cache": true,
+      "cache": false,
       "persistent": true,
       "dependsOn": ["^build"]
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"start": {
"cache": true,
"persistent": true,
"dependsOn": ["^build"]
},
"start": {
"cache": false,
"persistent": true,
"dependsOn": ["^build"]
},
🤖 Prompt for AI Agents
In `@turbo.json` around lines 40 - 44, The "start" task in turbo.json is marked as
persistent (persistent: true) but also has caching enabled (cache: true), which
is invalid for long-running tasks; update the "start" task configuration to set
cache to false so Turborepo doesn't attempt to cache a persistent task — locate
the "start" task entry and change its "cache" value from true to false while
leaving "persistent": true and "dependsOn": ["^build"] as-is.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 12, 2026

Deploying hackkit with  Cloudflare Pages  Cloudflare Pages

Latest commit: 63fdf70
Status:🚫  Build failed.

View logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant