feat: add logging for user and organization details in middleware and enhance organization creation with transaction support

This commit is contained in:
Rotimi Best
2026-03-11 14:38:03 +01:00
parent 1db55ec933
commit a5157f7c6d
6 changed files with 53 additions and 18 deletions
+3
View File
@@ -11,6 +11,7 @@ import { isUserOrgAdmin } from '@cio/db/queries/organization';
export const orgAdminMiddleware = async (c: Context, next: Next) => { export const orgAdminMiddleware = async (c: Context, next: Next) => {
try { try {
const user = c.get('user'); const user = c.get('user');
console.log('orgAdminMiddleware user', user);
if (!user) { if (!user) {
return c.json( return c.json(
{ {
@@ -23,6 +24,7 @@ export const orgAdminMiddleware = async (c: Context, next: Next) => {
} }
const orgId = c.req.header('cio-org-id'); const orgId = c.req.header('cio-org-id');
console.log('orgAdminMiddleware orgId', orgId);
if (!orgId) { if (!orgId) {
return c.json( return c.json(
@@ -36,6 +38,7 @@ export const orgAdminMiddleware = async (c: Context, next: Next) => {
} }
const isAdmin = await isUserOrgAdmin(orgId, user.id); const isAdmin = await isUserOrgAdmin(orgId, user.id);
console.log('orgAdminMiddleware isAdmin', isAdmin);
if (!isAdmin) { if (!isAdmin) {
return c.json( return c.json(
{ {
+1
View File
@@ -10,6 +10,7 @@ import { getUserOrgRole } from '@cio/db/queries/organization';
*/ */
export const orgMemberMiddleware = async (c: Context, next: Next) => { export const orgMemberMiddleware = async (c: Context, next: Next) => {
try { try {
console.log('user', c.get('user'));
const user = c.get('user'); const user = c.get('user');
if (!user) { if (!user) {
return c.json( return c.json(
@@ -10,6 +10,8 @@ import { isUserOrgTeamMember } from '@cio/db/queries/organization';
*/ */
export const orgTeamMemberMiddleware = async (c: Context, next: Next) => { export const orgTeamMemberMiddleware = async (c: Context, next: Next) => {
try { try {
console.log('orgTeamMemberMiddleware user', c.get('user'));
const user = c.get('user'); const user = c.get('user');
if (!user) { if (!user) {
return c.json( return c.json(
+35 -11
View File
@@ -4,6 +4,7 @@ import {
checkSiteNameExists, checkSiteNameExists,
createOrganization, createOrganization,
createOrganizationMember, createOrganizationMember,
createOrganizationPlan,
getOrganizationByProfileId, getOrganizationByProfileId,
getOrganizationCount getOrganizationCount
} from '@cio/db/queries'; } from '@cio/db/queries';
@@ -11,6 +12,7 @@ import { getProfileById, updateProfile } from '@cio/db/queries/auth';
import { env } from '@api/config/env'; import { env } from '@api/config/env';
import { ROLE } from '@cio/utils/constants'; import { ROLE } from '@cio/utils/constants';
import { PLAN } from '@cio/utils/plans';
import { db } from '@cio/db/drizzle'; import { db } from '@cio/db/drizzle';
import { sendEmail } from '@cio/email'; import { sendEmail } from '@cio/email';
@@ -39,18 +41,40 @@ export async function createOrganizationWithOwner(
// Business Logic: Create org and member in a transaction // Business Logic: Create org and member in a transaction
try { try {
const result = await db.transaction(async () => { const result = await db.transaction(async (tx) => {
const organization = await createOrganization({ const organization = await createOrganization(
name: input.orgName, {
siteName: input.siteName name: input.orgName,
}); siteName: input.siteName
},
tx
);
const member = await createOrganizationMember({ const member = await createOrganizationMember(
organizationId: organization.id, {
profileId, organizationId: organization.id,
roleId: ROLE.ADMIN, profileId,
verified: true roleId: ROLE.ADMIN,
}); verified: true
},
tx
);
// Self-hosted: assign Enterprise plan to the new org
if (env.PUBLIC_IS_SELFHOSTED === 'true') {
await createOrganizationPlan(
{
orgId: organization.id,
planName: PLAN.ENTERPRISE as 'ENTERPRISE',
subscriptionId: `selfhosted-${organization.id}`,
triggeredBy: member.id,
payload: {},
isActive: true,
provider: 'selfhosted'
},
tx
);
}
return { organization, member }; return { organization, member };
}); });
@@ -228,6 +228,7 @@ export function getApiHeaders(
.join('; '); .join('; ');
console.log('cioCookies', cioCookies); console.log('cioCookies', cioCookies);
console.log('cookies', cookies.getAll());
const headers: { cookie: string; 'cio-org-id'?: string } = { const headers: { cookie: string; 'cio-org-id'?: string } = {
cookie: cioCookies || '' cookie: cioCookies || ''
}; };
@@ -11,7 +11,7 @@ import type {
import { and, eq, inArray, or, sql } from 'drizzle-orm'; import { and, eq, inArray, or, sql } from 'drizzle-orm';
import { ROLE } from '@cio/utils/constants'; import { ROLE } from '@cio/utils/constants';
import { db } from '@db/drizzle'; import { db, type DbOrTxClient } from '@db/drizzle';
export function getOrgIdBySiteName(siteName: string) { export function getOrgIdBySiteName(siteName: string) {
return db.select().from(schema.organization).where(eq(schema.organization.siteName, siteName)).limit(1); return db.select().from(schema.organization).where(eq(schema.organization.siteName, siteName)).limit(1);
@@ -82,14 +82,14 @@ export const getOrganizationByProfileId = async (profileId: string): Promise<Org
})); }));
}; };
export const createOrganization = async (data: TNewOrganization) => { export const createOrganization = async (data: TNewOrganization, dbClient: DbOrTxClient = db) => {
const [organization] = await db.insert(schema.organization).values(data).returning(); const [organization] = await dbClient.insert(schema.organization).values(data).returning();
return organization; return organization;
}; };
export const createOrganizationMember = async (data: TNewOrganizationmember) => { export const createOrganizationMember = async (data: TNewOrganizationmember, dbClient: DbOrTxClient = db) => {
const [member] = await db.insert(schema.organizationmember).values(data).returning(); const [member] = await dbClient.insert(schema.organizationmember).values(data).returning();
return member; return member;
}; };
@@ -534,10 +534,14 @@ export const getOrganizationCount = async (): Promise<number> => {
/** /**
* Creates a new organization plan * Creates a new organization plan
* @param data Organization plan creation data * @param data Organization plan creation data
* @param dbClient Optional DB or transaction client for use within transactions
* @returns Created organization plan record * @returns Created organization plan record
*/ */
export const createOrganizationPlan = async (data: TNewOrganizationPlan): Promise<TOrganizationPlan> => { export const createOrganizationPlan = async (
const [plan] = await db.insert(schema.organizationPlan).values(data).returning(); data: TNewOrganizationPlan,
dbClient: DbOrTxClient = db
): Promise<TOrganizationPlan> => {
const [plan] = await dbClient.insert(schema.organizationPlan).values(data).returning();
return plan; return plan;
}; };