diff --git a/.github/workflows/production-release.yml b/.github/workflows/production-release.yml
new file mode 100644
index 0000000..316f038
--- /dev/null
+++ b/.github/workflows/production-release.yml
@@ -0,0 +1,198 @@
+name: Production Release
+
+on:
+ push:
+ branches:
+ - master
+ - main
+ workflow_dispatch:
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ production-release:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ packages: write
+ # Skip if the commit message contains the auto-increment marker to prevent infinite loops
+ if: "!contains(github.event.head_commit.message, 'đ¤ Auto-increment version')"
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "20"
+
+ - name: Update versions using comprehensive management script
+ id: version_update
+ run: |
+ # Make script executable
+ chmod +x .github/scripts/manage-versions.js
+
+ # Run the comprehensive version management script
+ node .github/scripts/manage-versions.js
+
+ # Display updated files
+ echo "Updated projectData.ts:"
+ cat apps/web/projectData.ts
+ echo ""
+ echo "Updated version.json:"
+ cat version.json
+
+ - name: Check for changes
+ id: git_status
+ run: |
+ if [ -n "$(git status --porcelain)" ]; then
+ echo "changes=true" >> $GITHUB_OUTPUT
+ else
+ echo "changes=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Commit version changes
+ if: steps.git_status.outputs.changes == 'true'
+ run: |
+ git config --local user.email "action@github.com"
+ git config --local user.name "GitHub Action"
+
+ # Add all changed files
+ git add apps/web/projectData.ts version.json
+
+ # Add version file if it was created
+ if [ -n "${{ steps.version_update.outputs.version_file }}" ]; then
+ git add "Versions/${{ steps.version_update.outputs.version_file }}"
+ fi
+
+ git commit -m "đ¤ Auto-increment version to ${{ steps.version_update.outputs.new_version }} (prod: ${{ steps.version_update.outputs.prod_version }}, dev: ${{ steps.version_update.outputs.dev_version }})"
+ git push
+
+ - name: Log in to the Container registry
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=raw,value=latest
+ type=raw,value=${{ steps.version_update.outputs.new_version }}
+ type=raw,value=${{ steps.version_update.outputs.prod_version }},enable={{isBranch 'master'}}
+ type=ref,event=branch
+ type=semver,pattern={{version}}
+ type=sha,prefix=
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ - name: Create version branch (stable releases only)
+ if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
+ run: |
+ # Create a new branch for this stable version
+ git checkout -b "release/v${{ steps.version_update.outputs.new_version }}"
+ git push origin "release/v${{ steps.version_update.outputs.new_version }}"
+
+ # Switch back to main branch
+ git checkout ${{ github.ref_name }}
+
+ - name: Generate release notes (stable releases only)
+ if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
+ id: release_notes
+ run: |
+ # Make script executable
+ chmod +x .github/scripts/generate-release-notes.js
+
+ # Generate release notes using the script
+ node .github/scripts/generate-release-notes.js "${{ steps.version_update.outputs.new_version }}"
+
+ - name: Create Git Tag (stable releases only)
+ if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
+ run: |
+ git tag v${{ steps.version_update.outputs.new_version }}
+ git push origin v${{ steps.version_update.outputs.new_version }}
+
+ - name: Create GitHub Release (stable releases only)
+ if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ # Use version file if created, otherwise use generated release notes
+ if [ -f "Versions/${{ steps.version_update.outputs.version_file }}" ]; then
+ NOTES_FILE="Versions/${{ steps.version_update.outputs.version_file }}"
+ else
+ NOTES_FILE="release-notes.md"
+ fi
+
+ # Create release using GitHub CLI
+ gh release create v${{ steps.version_update.outputs.new_version }} \
+ --title "Release v${{ steps.version_update.outputs.new_version }}" \
+ --notes-file "$NOTES_FILE" \
+ --latest
+
+ - name: Output summary
+ run: |
+ echo "## đ Production Release Summary" >> $GITHUB_STEP_SUMMARY
+ echo "- **Previous version:** ${{ steps.version_update.outputs.previous_version }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **New version:** ${{ steps.version_update.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Production version:** ${{ steps.version_update.outputs.prod_version }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Development version:** ${{ steps.version_update.outputs.dev_version }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Stable release:** ${{ steps.version_update.outputs.is_stable }}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ echo "### đŗ Docker Images Built" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "${{ steps.version_update.outputs.is_master }}" == "true" ]; then
+ echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.prod_version }}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ echo "### đ Files Updated" >> $GITHUB_STEP_SUMMARY
+ echo "- \`apps/web/projectData.ts\` - Updated to ${{ steps.version_update.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY
+ echo "- \`version.json\` - prod: ${{ steps.version_update.outputs.prod_version }}, dev: ${{ steps.version_update.outputs.dev_version }}" >> $GITHUB_STEP_SUMMARY
+
+ if [ -n "${{ steps.version_update.outputs.version_file }}" ]; then
+ echo "- \`Versions/${{ steps.version_update.outputs.version_file }}\` - New version file created" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "${{ steps.version_update.outputs.is_stable }}" == "true" ] && [ "${{ steps.version_update.outputs.is_master }}" == "true" ]; then
+ echo "### đˇī¸ Release Created" >> $GITHUB_STEP_SUMMARY
+ echo "- **Tag:** \`v${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
+ echo "- **Branch:** \`release/v${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
+ echo "- **Release:** [v${{ steps.version_update.outputs.new_version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version_update.outputs.new_version }})" >> $GITHUB_STEP_SUMMARY
+ if [ -n "${{ steps.version_update.outputs.version_file }}" ]; then
+ echo "- **Version File:** \`Versions/${{ steps.version_update.outputs.version_file }}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "### â ī¸ Development Build" >> $GITHUB_STEP_SUMMARY
+ if [ "${{ steps.version_update.outputs.is_master }}" != "true" ]; then
+ echo "This is a development branch build. No GitHub release or version branch created." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "This is a pre-release version (contains alpha, beta, canary, etc.). No GitHub release or version branch created." >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
diff --git a/.github/workflows/version-and-build.yml b/.github/workflows/version-and-build.yml
index 3030eb1..bbc29e5 100644
--- a/.github/workflows/version-and-build.yml
+++ b/.github/workflows/version-and-build.yml
@@ -1,7 +1,8 @@
name: Auto Update Version and Build
on:
- push:
+ pull_request:
+ types: [opened, synchronize, reopened]
branches:
- master
- main
@@ -17,8 +18,11 @@ jobs:
permissions:
contents: write
packages: write
- # Skip if the commit message contains the auto-increment marker to prevent infinite loops
- if: "!contains(github.event.head_commit.message, 'đ¤ Auto-increment version')"
+ # Only run for collaborators or repository owner
+ if: |
+ github.event.pull_request.author_association == 'OWNER' ||
+ github.event.pull_request.author_association == 'COLLABORATOR' ||
+ github.event.pull_request.author_association == 'MEMBER'
steps:
- name: Checkout repository
@@ -57,7 +61,7 @@ jobs:
echo "changes=false" >> $GITHUB_OUTPUT
fi
- - name: Commit version changes
+ - name: Commit version changes (PR only - no push)
if: steps.git_status.outputs.changes == 'true'
run: |
git config --local user.email "action@github.com"
@@ -72,7 +76,7 @@ jobs:
fi
git commit -m "đ¤ Auto-increment version to ${{ steps.version_update.outputs.new_version }} (prod: ${{ steps.version_update.outputs.prod_version }}, dev: ${{ steps.version_update.outputs.dev_version }})"
- git push
+ # Note: Not pushing changes in PR context - they will be available for review
- name: Log in to the Container registry
uses: docker/login-action@v3
@@ -87,13 +91,10 @@ jobs:
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
- type=raw,value=latest
- type=raw,value=${{ steps.version_update.outputs.new_version }}
- type=raw,value=${{ steps.version_update.outputs.prod_version }},enable={{isBranch 'master'}}
- type=ref,event=branch
+ type=raw,value=pr-${{ github.event.number }}
+ type=raw,value=${{ steps.version_update.outputs.new_version }}-pr-${{ github.event.number }}
type=ref,event=pr
- type=semver,pattern={{version}}
- type=sha,prefix=
+ type=sha,prefix=pr-${{ github.event.number }}-
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -108,68 +109,46 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
- - name: Create version branch (stable releases only)
- if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
- run: |
- # Create a new branch for this stable version
- git checkout -b "release/v${{ steps.version_update.outputs.new_version }}"
- git push origin "release/v${{ steps.version_update.outputs.new_version }}"
-
- # Switch back to main branch
- git checkout ${{ github.ref_name }}
-
- - name: Generate release notes (stable releases only)
- if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
- id: release_notes
- run: |
- # Make script executable
- chmod +x .github/scripts/generate-release-notes.js
+ - name: Add PR comment with build info
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const comment = `## đ CI/CD Build Summary for PR #${{ github.event.number }}
- # Generate release notes using the script
- node .github/scripts/generate-release-notes.js "${{ steps.version_update.outputs.new_version }}"
+ **Build Status:** â
Success
+ **Version:** ${{ steps.version_update.outputs.new_version }}
+ **Docker Images Built:**
+ - \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.number }}\`
+ - \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.new_version }}-pr-${{ github.event.number }}\`
- - name: Create Git Tag (stable releases only)
- if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
- run: |
- git tag v${{ steps.version_update.outputs.new_version }}
- git push origin v${{ steps.version_update.outputs.new_version }}
+ **Files Updated:**
+ - \`apps/web/projectData.ts\` - Updated to ${{ steps.version_update.outputs.new_version }}
+ - \`version.json\` - prod: ${{ steps.version_update.outputs.prod_version }}, dev: ${{ steps.version_update.outputs.dev_version }}
+ ${steps.version_update.outputs.version_file ? `- \`Versions/${{ steps.version_update.outputs.version_file }}\` - New version file created` : ''}
- - name: Create GitHub Release (stable releases only)
- if: steps.git_status.outputs.changes == 'true' && steps.version_update.outputs.is_stable == 'true' && steps.version_update.outputs.is_master == 'true'
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- # Use version file if created, otherwise use generated release notes
- if [ -f "Versions/${{ steps.version_update.outputs.version_file }}" ]; then
- NOTES_FILE="Versions/${{ steps.version_update.outputs.version_file }}"
- else
- NOTES_FILE="release-notes.md"
- fi
+ > **Note:** This is a PR build. No releases or version branches will be created until the PR is merged.`;
- # Create release using GitHub CLI
- gh release create v${{ steps.version_update.outputs.new_version }} \
- --title "Release v${{ steps.version_update.outputs.new_version }}" \
- --notes-file "$NOTES_FILE" \
- --latest
+ github.rest.issues.createComment({
+ issue_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ body: comment
+ });
- name: Output summary
run: |
- echo "## đ Comprehensive Version Update & Build Summary" >> $GITHUB_STEP_SUMMARY
+ echo "## đ PR Build Summary for #${{ github.event.number }}" >> $GITHUB_STEP_SUMMARY
echo "- **Previous version:** ${{ steps.version_update.outputs.previous_version }}" >> $GITHUB_STEP_SUMMARY
echo "- **New version:** ${{ steps.version_update.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Production version:** ${{ steps.version_update.outputs.prod_version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Development version:** ${{ steps.version_update.outputs.dev_version }}" >> $GITHUB_STEP_SUMMARY
- echo "- **Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
- echo "- **Stable release:** ${{ steps.version_update.outputs.is_stable }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **PR Author:** ${{ github.event.pull_request.user.login }}" >> $GITHUB_STEP_SUMMARY
+ echo "- **Author Association:** ${{ github.event.pull_request.author_association }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### đŗ Docker Images Built" >> $GITHUB_STEP_SUMMARY
- echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest\`" >> $GITHUB_STEP_SUMMARY
- echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
-
- if [ "${{ steps.version_update.outputs.is_master }}" == "true" ]; then
- echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.prod_version }}\`" >> $GITHUB_STEP_SUMMARY
- fi
+ echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.number }}\`" >> $GITHUB_STEP_SUMMARY
+ echo "- \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version_update.outputs.new_version }}-pr-${{ github.event.number }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### đ Files Updated" >> $GITHUB_STEP_SUMMARY
@@ -181,19 +160,7 @@ jobs:
fi
echo "" >> $GITHUB_STEP_SUMMARY
- if [ "${{ steps.version_update.outputs.is_stable }}" == "true" ] && [ "${{ steps.version_update.outputs.is_master }}" == "true" ]; then
- echo "### đˇī¸ Release Created" >> $GITHUB_STEP_SUMMARY
- echo "- **Tag:** \`v${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
- echo "- **Branch:** \`release/v${{ steps.version_update.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY
- echo "- **Release:** [v${{ steps.version_update.outputs.new_version }}](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version_update.outputs.new_version }})" >> $GITHUB_STEP_SUMMARY
- if [ -n "${{ steps.version_update.outputs.version_file }}" ]; then
- echo "- **Version File:** \`Versions/${{ steps.version_update.outputs.version_file }}\`" >> $GITHUB_STEP_SUMMARY
- fi
- else
- echo "### â ī¸ Development Build" >> $GITHUB_STEP_SUMMARY
- if [ "${{ steps.version_update.outputs.is_master }}" != "true" ]; then
- echo "This is a development branch build. No GitHub release or version branch created." >> $GITHUB_STEP_SUMMARY
- else
- echo "This is a pre-release version (contains alpha, beta, canary, etc.). No GitHub release or version branch created." >> $GITHUB_STEP_SUMMARY
- fi
- fi
+ echo "### âšī¸ PR Build Notes" >> $GITHUB_STEP_SUMMARY
+ echo "This is a pull request build. No releases, tags, or version branches will be created." >> $GITHUB_STEP_SUMMARY
+ echo "Version changes are committed locally for review but not pushed to the repository." >> $GITHUB_STEP_SUMMARY
+ echo "Once the PR is merged, you may want to run a separate workflow for production deployments." >> $GITHUB_STEP_SUMMARY
diff --git a/apps/web/package.json b/apps/web/package.json
index e3f95b8..05d4174 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -32,7 +32,7 @@
"geist": "^1.5.1",
"lucide-react": "^0.546.0",
"marked-react": "^3.0.2",
- "next": "^16.0.7",
+ "next": "^16.0.10",
"next-themes": "^0.4.6",
"prism-react-renderer": "^2.4.1",
"radix-ui": "^1.4.3",
diff --git a/apps/web/projectData.ts b/apps/web/projectData.ts
index 52b83a7..93b0c8b 100644
--- a/apps/web/projectData.ts
+++ b/apps/web/projectData.ts
@@ -1,5 +1,5 @@
const data = {
- version: "0.1.10",
+ version: "0.1.12",
};
export default data;
diff --git a/apps/web/src/app/api/data/system_info/route.ts b/apps/web/src/app/api/data/system_info/route.ts
new file mode 100644
index 0000000..8e6132e
--- /dev/null
+++ b/apps/web/src/app/api/data/system_info/route.ts
@@ -0,0 +1,35 @@
+import type { NextRequest } from "next/server";
+import projectData from "../../../../../projectData";
+import {
+ db,
+ dorm,
+ main_schema,
+} from "../../../../../../../packages/db/src/index";
+
+export const GET = async (request: NextRequest) => {
+ const getHomePageStatus = await db
+ .select()
+ .from(main_schema.kvData)
+ .where(dorm.eq(main_schema.kvData.key, "homePageStatus"));
+ const getSearchPageStatus = await db
+ .select()
+ .from(main_schema.kvData)
+ .where(dorm.eq(main_schema.kvData.key, "searchStatus"));
+ const getCopyrightOwner = await db
+ .select()
+ .from(main_schema.kvData)
+ .where(dorm.eq(main_schema.kvData.key, "copyrightOwner"));
+ const exposeVersion = await db
+ .select()
+ .from(main_schema.kvData)
+ .where(dorm.eq(main_schema.kvData.key, "exposeVersion"));
+ return Response.json({
+ copyright_owner: getCopyrightOwner[0].value,
+ feature_status: {
+ homePage: getHomePageStatus[0].value !== "false",
+ search: getSearchPageStatus[0].value !== "false",
+ },
+ optionalExposeVersion: exposeVersion[0].value !== "false",
+ version: exposeVersion[0].value !== "false" ? projectData.version : null,
+ });
+};
diff --git a/apps/web/src/components/imageView.tsx b/apps/web/src/components/imageView.tsx
new file mode 100644
index 0000000..a491350
--- /dev/null
+++ b/apps/web/src/components/imageView.tsx
@@ -0,0 +1,34 @@
+"use client";
+import { XIcon } from "lucide-react";
+import Image from "next/image";
+
+export default function ImageView({
+ imageSrc,
+ closeState,
+}: {
+ imageSrc: string;
+ closeState: () => void;
+}) {
+ return (
+ <>
+
([]);
const [logUserInfo, setLogUserInfo] = useState<
@@ -160,6 +165,14 @@ export function PublicPostsAndVideos({
return (
+ {imageViewSys.previewOn && (
+
+ setImageViewSys({ previewOn: false, previewImageUrl: "" })
+ }
+ />
+ )}
{mode === "search" ? (
<>
@@ -197,7 +210,15 @@ export function PublicPostsAndVideos({
{i.textData}
{i.type === "photos" ? (
-
+
-
+
) : (
i.type === "video" && (
@@ -295,7 +316,16 @@ export function PublicPostsAndVideos({
{i.textData}
{i.type === "photos" ? (
-
+
-
+
) : (
i.type === "video" && (
diff --git a/bun.lock b/bun.lock
index 28f27ec..e89a3ee 100644
--- a/bun.lock
+++ b/bun.lock
@@ -7,6 +7,7 @@
"dependencies": {
"dotenv": "^17.2.3",
"geist": "^1.5.1",
+ "next": "^16.0.10",
"pg": "^8.16.3",
"zod": "^4.1.12",
},
@@ -43,7 +44,7 @@
"geist": "^1.5.1",
"lucide-react": "^0.546.0",
"marked-react": "^3.0.2",
- "next": "^16.0.7",
+ "next": "^16.0.10",
"next-themes": "^0.4.6",
"prism-react-renderer": "^2.4.1",
"radix-ui": "^1.4.3",
@@ -357,23 +358,23 @@
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
- "@next/env": ["@next/env@16.0.7", "", {}, "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw=="],
+ "@next/env": ["@next/env@16.0.10", "", {}, "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang=="],
- "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg=="],
+ "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg=="],
- "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA=="],
+ "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw=="],
- "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww=="],
+ "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw=="],
- "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g=="],
+ "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw=="],
- "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA=="],
+ "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.10", "", { "os": "linux", "cpu": "x64" }, "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA=="],
- "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w=="],
+ "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.10", "", { "os": "linux", "cpu": "x64" }, "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g=="],
- "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q=="],
+ "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg=="],
- "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.7", "", { "os": "win32", "cpu": "x64" }, "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug=="],
+ "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.10", "", { "os": "win32", "cpu": "x64" }, "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q=="],
"@noble/ciphers": ["@noble/ciphers@2.0.1", "", {}, "sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g=="],
@@ -867,7 +868,7 @@
"nanostores": ["nanostores@1.0.1", "", {}, "sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw=="],
- "next": ["next@16.0.7", "", { "dependencies": { "@next/env": "16.0.7", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.7", "@next/swc-darwin-x64": "16.0.7", "@next/swc-linux-arm64-gnu": "16.0.7", "@next/swc-linux-arm64-musl": "16.0.7", "@next/swc-linux-x64-gnu": "16.0.7", "@next/swc-linux-x64-musl": "16.0.7", "@next/swc-win32-arm64-msvc": "16.0.7", "@next/swc-win32-x64-msvc": "16.0.7", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A=="],
+ "next": ["next@16.0.10", "", { "dependencies": { "@next/env": "16.0.10", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.10", "@next/swc-darwin-x64": "16.0.10", "@next/swc-linux-arm64-gnu": "16.0.10", "@next/swc-linux-arm64-musl": "16.0.10", "@next/swc-linux-x64-gnu": "16.0.10", "@next/swc-linux-x64-musl": "16.0.10", "@next/swc-win32-arm64-msvc": "16.0.10", "@next/swc-win32-x64-msvc": "16.0.10", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA=="],
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
@@ -893,7 +894,7 @@
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
- "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
+ "postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
"postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
@@ -1065,9 +1066,9 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
- "@types/pg/@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="],
+ "@tailwindcss/postcss/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
- "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
+ "@types/pg/@types/node": ["@types/node@22.19.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA=="],
"radix-ui/@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="],
diff --git a/package.json b/package.json
index 4210ec0..fb2b92c 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"dependencies": {
"dotenv": "^17.2.3",
"geist": "^1.5.1",
+ "next": "^16.0.10",
"pg": "^8.16.3",
"zod": "^4.1.12"
},
diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts
index 2d16d7d..88f8667 100644
--- a/packages/auth/src/index.ts
+++ b/packages/auth/src/index.ts
@@ -1,6 +1,6 @@
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { betterAuth } from "better-auth";
-import { db } from "@devlogs_hosting/db";
+import { db, dorm, main_schema } from "@devlogs_hosting/db";
import * as schema from "@devlogs_hosting/db/schema/auth";
import { admin } from "better-auth/plugins";
@@ -28,6 +28,15 @@ export const auth = betterAuth({
user: {
create: {
before: async (user, ctx) => {
+ const checkIfSystemDisabledRegister = await db
+ .select()
+ .from(main_schema.kvData)
+ .where(dorm.eq(main_schema.kvData.key, "registrationStatus"))
+ .limit(1);
+ console.log(checkIfSystemDisabledRegister[0]);
+ if (checkIfSystemDisabledRegister[0]?.value === false) {
+ throw new Error("Registration is disabled");
+ }
try {
// Query database directly using your existing Drizzle connection
const existingUsers = await db
diff --git a/packages/db/src/migrations/0014_reflective_roughhouse.sql b/packages/db/src/migrations/0014_reflective_roughhouse.sql
new file mode 100644
index 0000000..860be5c
--- /dev/null
+++ b/packages/db/src/migrations/0014_reflective_roughhouse.sql
@@ -0,0 +1,4 @@
+INSERT INTO kv_data (key, value) VALUES
+('copyrightOwner', 'Default Owner'),
+('exposeVersion', 'false'),
+ON CONFLICT DO NOTHING;
diff --git a/packages/db/src/migrations/meta/0014_snapshot.json b/packages/db/src/migrations/meta/0014_snapshot.json
new file mode 100644
index 0000000..a1a81e5
--- /dev/null
+++ b/packages/db/src/migrations/meta/0014_snapshot.json
@@ -0,0 +1,733 @@
+{
+ "id": "74388b03-2115-4afd-aa95-12191611747b",
+ "prevId": "2e425149-7760-4ca5-9703-57c44adde47d",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "account_id": {
+ "name": "account_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider_id": {
+ "name": "provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token_expires_at": {
+ "name": "access_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "refresh_token_expires_at": {
+ "name": "refresh_token_expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "password": {
+ "name": "password",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_user_id_user_id_fk": {
+ "name": "account_user_id_user_id_fk",
+ "tableFrom": "account",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "ip_address": {
+ "name": "ip_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_agent": {
+ "name": "user_agent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "impersonated_by": {
+ "name": "impersonated_by",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_user_id_user_id_fk": {
+ "name": "session_user_id_user_id_fk",
+ "tableFrom": "session",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "session_token_unique": {
+ "name": "session_token_unique",
+ "columns": [
+ "token"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email_verified": {
+ "name": "email_verified",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "banned": {
+ "name": "banned",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "ban_reason": {
+ "name": "ban_reason",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ban_expires": {
+ "name": "ban_expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verification": {
+ "name": "verification",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.collections": {
+ "name": "collections",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "identity": {
+ "name": "collections_id_seq",
+ "increment": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "startWith": "1",
+ "cache": "1",
+ "cycle": false,
+ "schema": "public",
+ "type": "byDefault"
+ }
+ },
+ "collection_id": {
+ "name": "collection_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "items": {
+ "name": "items",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'::jsonb"
+ },
+ "by_user": {
+ "name": "by_user",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "collections_by_user_user_id_fk": {
+ "name": "collections_by_user_user_id_fk",
+ "tableFrom": "collections",
+ "columnsFrom": [
+ "by_user"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "collections_collection_id_unique": {
+ "name": "collections_collection_id_unique",
+ "columns": [
+ "collection_id"
+ ],
+ "nullsNotDistinct": false
+ },
+ "collections_slug_unique": {
+ "name": "collections_slug_unique",
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.kv_data": {
+ "name": "kv_data",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "identity": {
+ "name": "kv_data_id_seq",
+ "increment": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "startWith": "1",
+ "cache": "1",
+ "cycle": false,
+ "schema": "public",
+ "type": "byDefault"
+ }
+ },
+ "key": {
+ "name": "key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "value": {
+ "name": "value",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "kv_data_key_unique": {
+ "name": "kv_data_key_unique",
+ "columns": [
+ "key"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.url_shorter": {
+ "name": "url_shorter",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "identity": {
+ "name": "url_shorter_id_seq",
+ "increment": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "startWith": "1",
+ "cache": "1",
+ "cycle": false,
+ "schema": "public",
+ "type": "byDefault"
+ }
+ },
+ "url_slug": {
+ "name": "url_slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "target_url": {
+ "name": "target_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "by_user": {
+ "name": "by_user",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "url_shorter_by_user_user_id_fk": {
+ "name": "url_shorter_by_user_user_id_fk",
+ "tableFrom": "url_shorter",
+ "columnsFrom": [
+ "by_user"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "url_shorter_url_slug_unique": {
+ "name": "url_shorter_url_slug_unique",
+ "columns": [
+ "url_slug"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_posts": {
+ "name": "user_posts",
+ "schema": "",
+ "columns": {
+ "post_id": {
+ "name": "post_id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "by_user": {
+ "name": "by_user",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "text_data": {
+ "name": "text_data",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image_url": {
+ "name": "image_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "video_url": {
+ "name": "video_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'draft'"
+ },
+ "tags": {
+ "name": "tags",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'[]'::jsonb"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "title_search_index": {
+ "name": "title_search_index",
+ "columns": [
+ {
+ "expression": "to_tsvector('english', \"text_data\")",
+ "isExpression": true,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gin",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "user_posts_by_user_user_id_fk": {
+ "name": "user_posts_by_user_user_id_fk",
+ "tableFrom": "user_posts",
+ "columnsFrom": [
+ "by_user"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {
+ "type_check": {
+ "name": "type_check",
+ "value": "\"user_posts\".\"type\" IN ('photos', 'text', 'video')"
+ },
+ "checkcorrectstatus": {
+ "name": "checkcorrectstatus",
+ "value": "\"user_posts\".\"status\" IN ('draft', 'private', 'public', 'unlisted')"
+ },
+ "image_url_check": {
+ "name": "image_url_check",
+ "value": "\"user_posts\".\"type\" != 'photos' OR \"user_posts\".\"image_url\" IS NOT NULL"
+ },
+ "video_url_check": {
+ "name": "video_url_check",
+ "value": "\"user_posts\".\"type\" != 'video' OR \"user_posts\".\"video_url\" IS NOT NULL"
+ }
+ },
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {},
+ "schemas": {},
+ "views": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/packages/db/src/migrations/meta/_journal.json b/packages/db/src/migrations/meta/_journal.json
index e63835c..1df7ba2 100644
--- a/packages/db/src/migrations/meta/_journal.json
+++ b/packages/db/src/migrations/meta/_journal.json
@@ -99,6 +99,13 @@
"when": 1764485135340,
"tag": "0013_clear_rockslide",
"breakpoints": true
+ },
+ {
+ "idx": 14,
+ "version": "7",
+ "when": 1765554089478,
+ "tag": "0014_reflective_roughhouse",
+ "breakpoints": true
}
]
}
\ No newline at end of file