Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/prettier.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,378 changes: 1,378 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion drizzle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dotenv.config({

export default defineConfig({
out: "./migrations",
schema: "./src/backend/schemas/schemas.ts",
schema: "./src/backend/persistence/schema.ts",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"sqlkit": "^1.0.13",
"tailwind-merge": "^3.0.2",
"tw-animate-css": "^1.2.4",
"use-immer": "^0.11.0",
"zod": "^3.24.2"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const page: React.FC<Props> = async ({ params }) => {
],
});

const aggregatedTags = await persistenceRepository.articleTag.find({
const aggregatedTags = await persistenceRepository.articleTagPivot.find({
where: inArray("article_id", [article.id]),
joins: [
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/play/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function GET(request: Request) {
// }
// ]
return NextResponse.json({
handle: await persistenceRepository.articleTag.delete({
handle: await persistenceRepository.articleTagPivot.delete({
where: {
AND: [
{
Expand Down
6 changes: 5 additions & 1 deletion src/app/dashboard/_components/ArticleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ const ArticleList = () => {
}}
>
<CardStackIcon />
<span>{_t("Make Unpublished")}</span>
<span>
{article.is_published
? _t("Make Draft")
: _t("Publish article")}
</span>
</button>
</DropdownMenuItem>
</DropdownMenuContent>
Expand Down
5 changes: 0 additions & 5 deletions src/backend/database.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/backend/models/models.ts

This file was deleted.

23 changes: 23 additions & 0 deletions src/backend/persistence/clients.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import "dotenv/config";
import { PostgresAdapter } from "sqlkit";
import { drizzle } from "drizzle-orm/node-postgres";
import * as schema from "./schemas";
import { Pool } from "pg";
import { env } from "@/env";

declare global {
var pgClient: PostgresAdapter | undefined;
}

export const drizzleClient = drizzle(process.env.DATABASE_URL!, { schema });

// Initialize global database connection
if (!globalThis.pgClient) {
const pool = new Pool({
connectionString: env.DATABASE_URL,
});

globalThis.pgClient = new PostgresAdapter(pool);
}

export const pgClient = globalThis.pgClient;

This file was deleted.

18 changes: 0 additions & 18 deletions src/backend/persistence/database-drivers/pg.client.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/backend/persistence/persistence-contracts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
export enum DatabaseTableName {
tenants = "tenants",
clients = "clients",
users = "users",
roles = "roles",
articles = "articles",
user_socials = "user_socials",
user_sessions = "user_sessions",
Expand Down
32 changes: 22 additions & 10 deletions src/backend/persistence/persistence-repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,62 @@ import {
UserSession,
UserSocial,
} from "../models/domain-models";
import { pgClient } from "./database-drivers/pg.client";
import { pgClient } from "./clients";
import { DatabaseTableName } from "./persistence-contracts";

const repositoryConfig = {
logging: true,
};

export const userRepository = new Repository<User>(
DatabaseTableName.users,
pgClient
pgClient,
repositoryConfig
);
export const articleRepository = new Repository<Article>(
DatabaseTableName.articles,
pgClient
pgClient,
repositoryConfig
);
export const tagRepository = new Repository<Tag>(
DatabaseTableName.tags,
pgClient
pgClient,
repositoryConfig
);
export const articleTagRepository = new Repository<ArticleTag>(
DatabaseTableName.article_tag,
pgClient
pgClient,
repositoryConfig
);
export const userSocialRepository = new Repository<UserSocial>(
DatabaseTableName.user_socials,
pgClient
pgClient,
repositoryConfig
);
export const userSessionRepository = new Repository<UserSession>(
DatabaseTableName.user_sessions,
pgClient
pgClient,
repositoryConfig
);

const seriesRepository = new Repository<Series>(
DatabaseTableName.series,
pgClient
pgClient,
repositoryConfig
);

const seriesItemsRepository = new Repository<SeriesItem>(
DatabaseTableName.series_items,
pgClient
pgClient,
repositoryConfig
);

export const persistenceRepository = {
user: userRepository,
userSocial: userSocialRepository,
userSession: userSessionRepository,
article: articleRepository,
articleTag: articleTagRepository,
articleTagPivot: articleTagRepository,
tags: tagRepository,
series: seriesRepository,
seriesItems: seriesItemsRepository,
Expand Down
File renamed without changes.
34 changes: 1 addition & 33 deletions src/backend/services/article.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,15 @@ import * as sk from "sqlkit";
import { and, desc, eq, like, neq, or } from "sqlkit";
import { z } from "zod";
import { Article, User } from "../models/domain-models";
import { pgClient } from "../persistence/database-drivers/pg.client";
import { DatabaseTableName } from "../persistence/persistence-contracts";
import { persistenceRepository } from "../persistence/persistence-repositories";
import {
handleRepositoryException,
RepositoryException,
} from "./RepositoryException";
import { ArticleRepositoryInput } from "./inputs/article.input";
import { getSessionUserId } from "./session.actions";
import { syncTagsWithArticles } from "./tag.action";
import { persistenceRepository } from "../persistence/persistence-repositories";

/**
* Creates a new article in the database.
*
* @param _input - The article data to create, validated against ArticleRepositoryInput.createArticleInput schema
* @returns Promise<Article> - The newly created article
* @throws {RepositoryException} If article creation fails or validation fails
*/
export async function createArticle(
_input: z.infer<typeof ArticleRepositoryInput.createArticleInput>
) {
try {
const input =
await ArticleRepositoryInput.createArticleInput.parseAsync(_input);
const article = await persistenceRepository.article.insert([
{
title: input.title,
handle: input.handle,
excerpt: input.excerpt ?? null,
body: input.body ?? null,
cover_image: input.cover_image ?? null,
is_published: input.is_published ?? false,
published_at: input.is_published ? new Date() : null,
author_id: input.author_id,
},
]);
return article;
} catch (error) {
handleRepositoryException(error);
}
}

export async function createMyArticle(
_input: z.infer<typeof ArticleRepositoryInput.createMyArticleInput>
Expand Down
22 changes: 11 additions & 11 deletions src/backend/services/dashboard.action.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
"use server";

import * as sessionActions from "@/backend/services/session.actions";
import { persistenceRepository } from "../persistence/persistence-repositories";
import { pgClient } from "@/backend/persistence/clients";

const sql = String.raw;

const query = sql`
SELECT (SELECT Count(*)
FROM articles
WHERE author_id = $1)
AS total_articles,
(SELECT Count(*)
FROM comments
WHERE comments.commentable_type = 'ARTICLE'
AND comments.commentable_id IN (SELECT id
FROM articles
WHERE articles.author_id = $1))
AS total_comments
FROM articles
WHERE author_id = $1)
AS total_articles,
(SELECT Count(*)
FROM comments
WHERE comments.commentable_type = 'ARTICLE'
AND comments.commentable_id IN (SELECT id
FROM articles
WHERE articles.author_id = $1))
AS total_comments
`;

export async function myArticleMatrix() {
Expand Down
2 changes: 1 addition & 1 deletion src/backend/services/inputs/article.input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const ArticleRepositoryInput = {
})
.optional(),

// Optional boolean flag for publish status
// Optional boolean flag for publication status
is_published: z.boolean().optional(),

tag_ids: z.array(z.string()).optional().nullable(),
Expand Down
17 changes: 7 additions & 10 deletions src/backend/services/oauth/GithubOAuthService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { generateRandomString } from "@/lib/utils";
import { IGithubUser, IOAuthService } from "./oauth-contract";
import { cookies } from "next/headers";
import { env } from "@/env";
import {generateRandomString} from "@/lib/utils";
import {IGithubUser, IOAuthService} from "./oauth-contract";
import {cookies} from "next/headers";
import {env} from "@/env";

export class GithubOAuthService implements IOAuthService<IGithubUser> {
async getAuthorizationUrl(): Promise<string> {
Expand Down Expand Up @@ -41,8 +41,7 @@ export class GithubOAuthService implements IOAuthService<IGithubUser> {
env.GITHUB_CALLBACK_URL
);

const githubUser = await getGithubUser(githubAccessToken.access_token);
return githubUser;
return await getGithubUser(githubAccessToken.access_token);
}
}

Expand Down Expand Up @@ -79,8 +78,7 @@ export const validateGitHubCode = async (
throw new Error("Failed to validate GitHub code");
}

const data = await response.json();
return data;
return await response.json();
};

const getGithubUser = async (accessToken: string): Promise<IGithubUser> => {
Expand All @@ -93,6 +91,5 @@ const getGithubUser = async (accessToken: string): Promise<IGithubUser> => {
throw new Error("Failed to get GitHub user");
}

const githubUserResponse = (await githubAPI.json()) as IGithubUser;
return githubUserResponse;
return (await githubAPI.json()) as IGithubUser;
};
Loading