Skip to content
Open
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
9 changes: 8 additions & 1 deletion src/app/api/export/[section]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,14 @@ export async function buildExport(
default: {
if (section.startsWith("custom:")) {
const slug = section.slice("custom:".length);
const template = await SectionTemplate.findOne({ slug }).lean();
const template = await SectionTemplate.findOne({
slug,
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true, usageCount: { $gte: 3 } },
],
}).lean();
if (!template) {
return { name: "Unknown", columns: [], rows: [] };
}
Expand Down
9 changes: 8 additions & 1 deletion src/app/api/sections/[slug]/entries/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ export async function PATCH(
return NextResponse.json({ error: "Not found" }, { status: 404 });
}

const template = await SectionTemplate.findOne({ slug }).lean();
const template = await SectionTemplate.findOne({
slug,
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true, usageCount: { $gte: 3 } },
],
}).lean();
if (!template) {
return NextResponse.json({ error: "Section not found" }, { status: 404 });
}
Expand Down
18 changes: 16 additions & 2 deletions src/app/api/sections/[slug]/entries/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ export async function GET(
await connectDB();
const { slug } = await params;

const template = await SectionTemplate.findOne({ slug }).lean();
const template = await SectionTemplate.findOne({
slug,
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true, usageCount: { $gte: 3 } },
],
}).lean();
if (!template) {
return NextResponse.json({ error: "Section not found" }, { status: 404 });
}
Expand Down Expand Up @@ -89,7 +96,14 @@ export async function POST(
await connectDB();
const { slug } = await params;

const template = await SectionTemplate.findOne({ slug }).lean();
const template = await SectionTemplate.findOne({
slug,
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true, usageCount: { $gte: 3 } },
],
}).lean();
if (!template) {
return NextResponse.json({ error: "Section not found" }, { status: 404 });
}
Expand Down
14 changes: 11 additions & 3 deletions src/app/api/sections/templates/[slug]/edit-layout/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,14 @@ export async function POST(
await connectDB();
const { slug } = await params;

const template = await SectionTemplate.findOne({ slug });
const template = await SectionTemplate.findOne({
slug,
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true, usageCount: { $gte: 3 } },
],
});
if (!template) {
return NextResponse.json({ error: "Template not found" }, { status: 404 });
}
Expand Down Expand Up @@ -381,8 +388,9 @@ Output ONLY the complete updated HTML:`;
.replace(/\n?```$/i, "")
.trim();

// Optionally save to template
if (body.save) {
// Optionally save to template — only the owner may persist changes, even
// though a shared/built-in template can be read here for AI context.
if (body.save && String(template.createdBy) === String(userId)) {
template.layoutHtml = cleaned;
await template.save();
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/sections/templates/[slug]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function GET(
$or: [
{ createdBy: userId },
{ createdBy: null },
{ isShared: true },
{ isShared: true, usageCount: { $gte: 3 } },
],
}).lean();

Expand Down
1 change: 1 addition & 0 deletions src/app/api/sections/templates/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export async function POST(req: NextRequest) {
isBuiltIn: false,
createdBy: userId,
usageCount: 1,
isShared: false,
});

// Add to user's customSections
Expand Down
4 changes: 2 additions & 2 deletions src/lib/__tests__/section-template.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ describe("SectionTemplate schema", () => {
expect(instance.forkCount).toBe(0);
});

it("has isShared field as Boolean defaulting to true", () => {
it("has isShared field as Boolean defaulting to false (private unless explicitly shared)", () => {
const schemaPaths = SectionTemplate.schema.paths;
expect(schemaPaths["isShared"]).toBeDefined();
const instance = new SectionTemplate({ name: "Test", slug: "test", icon: "Star" });
expect(instance.isShared).toBe(true);
expect(instance.isShared).toBe(false);
});

it("has isShared + usageCount compound index defined", () => {
Expand Down
4 changes: 3 additions & 1 deletion src/lib/models/section-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ const SectionTemplateSchema = new Schema<ISectionTemplate>(
sourcePrompt: { type: String, default: "" },
forkedFrom: { type: Schema.Types.ObjectId, ref: "SectionTemplate", default: null },
forkCount: { type: Number, default: 0 },
isShared: { type: Boolean, default: true },
// Private by default — only the shared-template-pool save path
// (src/lib/embeddings.ts) should set this true explicitly.
isShared: { type: Boolean, default: false },
},
{ timestamps: true }
);
Expand Down
4 changes: 4 additions & 0 deletions src/lib/profile/persist-sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface TemplateDoc {
isBuiltIn: boolean;
createdBy: string;
usageCount: number;
isShared: boolean;
sourceDimension?: string;
sourceFacetKey?: string;
}
Expand Down Expand Up @@ -57,6 +58,9 @@ export function buildTemplateDoc(
isBuiltIn: false,
createdBy: userId,
usageCount: 1,
// Personal, profile-generated sections describe the user's actual life
// (name/description/layout) — never share them by default.
isShared: false,
...(source?.dimension ? { sourceDimension: source.dimension } : {}),
...(source?.facetKey ? { sourceFacetKey: source.facetKey } : {}),
};
Expand Down