Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

DeenNotes AI

Mobile-first web app: turn khutbah notes, lectures, Quran reflections, halaqa notes, and reminders into structured summaries, action steps, and shareable cards—not fatwas or rulings.

Public repo safety

Treat this repo as safe to make public: tracked files must not contain database passwords, Supabase service_role or secret keys, AI provider keys, JWTs, or real Project Refs. Clone .env.example to .env.local (or .env), add your values only on your machine, and rely on .gitignore (.env* with an exception for .env.example). The Next.js app uses the anon/publishable client key with RLS; SUPABASE_SERVICE_ROLE_KEY is optional and not used by app routes—never prefix it with NEXT_PUBLIC_.

Beta launch checklist

Before inviting the first ~10 beta users:

  1. Database — Run supabase/migrations/001_init.sql. If this project ran an older 001 without short_summary / main_reminder, also run supabase/migrations/002_short_summary_main_reminder.sql. Confirm RLS stays enabled on profiles, deen_notes, and saved_share_cards (see verification SQL below).
  2. Supabase Auth — Site URL and redirect URLs match your deployment (/auth/callback). Decide production email confirmation behavior.
  3. Environment — Set variables from .env.example on the host. Prefer NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY; NEXT_PUBLIC_SUPABASE_ANON_KEY is an optional fallback when publishable is unset. Never put service_role in NEXT_PUBLIC_*; keep SUPABASE_SERVICE_ROLE_KEY server-only and out of the browser bundle.
  4. AI — Verify AI_PROVIDER and API keys; smoke-test note generation in staging.
  5. QA — Complete and sign off docs/MVP_LAUNCH_QA.md.
  6. Positioning — Copy stays humble: journal and reflection, not scholar or fatwa replacement.

Stack

  • Next.js App Router, TypeScript, Tailwind CSS
  • Supabase Auth + Postgres (RLS)
  • Pluggable AI: OpenAI, Anthropic, or Groq (AI_PROVIDER)

Prerequisites

  • Node.js 20+
  • A Supabase project
  • An API key for at least one AI provider
  • Optional: Supabase CLI for db push
  • Optional: Netlify CLI (installed in this repo as a dev dependency — use npm run ntl -- … from the repo root)

Netlify CLI

From the repo root, the CLI is available without a global install:

npm run ntl -- --version
npm run ntl -- status
npm run ntl -- link
npm run netlify:deploy
npm run netlify:deploy:prod

For non-interactive use (agents, CI, scripts), set NETLIFY_AUTH_TOKEN in .env.local (create a personal access token under Netlify → User settings → Applications). For a one-time interactive login on your machine: npm run ntl -- login.

Supabase CLI workflow

From the repo root (after installing the CLI):

For this project, use your Supabase dashboard Project Ref when linking locally. Find it under Project Settings → General (not the full database password).

supabase login
supabase init
supabase link --project-ref YOUR_PROJECT_REF
supabase db push
  • supabase init creates supabase/config.toml if you do not already have it; keep migration SQL in supabase/migrations/ as the source of truth.

If supabase db push fails with “already exists” (you already ran 001_init.sql in the SQL Editor), the remote DB matches that migration but Supabase’s history does not yet. Mark it applied, then push again:

supabase migration repair 001 --status applied --linked
supabase db push

Use 002 instead of 001 if only the second migration was applied manually. Run supabase migration list to see local vs remote status.

Verify schema and RLS after db push

Run in SQL Editor (or supabase db execute):

-- Tables exist in public schemaselect table_name
frominformation_schema.tableswhere table_schema ='public'and table_name in ('profiles', 'deen_notes', 'saved_share_cards')
order by table_name;
-- RLS enabled (relrowsecurity should be true for each)selectc.relnameas table_name, c.relrowsecurityas rls_enabled
from pg_class c
join pg_namespace n onn.oid=c.relnamespacewheren.nspname='public'andc.relkind='r'andc.relnamein ('profiles', 'deen_notes', 'saved_share_cards')
order by1;

Expect three rows in the first query and rls_enabled = true for all three in the second. Policies in the migrations scope access by auth.uid() for tenant-owned rows.

Setup

  1. Clone and install

    npm install
  2. Configure Supabase

    • Settings → API: copy project URL (e.g. https://YOUR_PROJECT_REF.supabase.co) and the publishable client key (or legacy anon key — same permission level; never the service_role key for NEXT_PUBLIC_*).
    • Authentication → URL configuration: set Site URL to http://localhost:3000 (and your production URL on Vercel).
    • Redirects: http://localhost:3000/auth/callback (and https://your-domain.com/auth/callback in production).
  3. Database

    If Postgres errors on execute function for triggers, use execute procedure for the same trigger names (see Supabase/Postgres docs for your version).

  4. Environment variables

    cp .env.example .env.local

    Fill in at minimum: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY (preferred) or NEXT_PUBLIC_SUPABASE_ANON_KEY, AI_PROVIDER, the matching model env (OPENAI_MODEL / ANTHROPIC_MODEL / GROQ_MODEL), and that provider’s API key. Do not commit .env.local.

  5. Auth for local dev

    • Under Authentication → Providers → Email, consider disabling Confirm email while developing so sign-up can log in immediately. Re-enable for production.
  6. Run the app

    npm run dev

    Open http://localhost:3000.

Deploy on Vercel

  • Import the repo; set the same env vars in the Vercel project (including optional SUPABASE_SERVICE_ROLE_KEY only if you add server jobs that need it—never as a public var).
  • Point Supabase Site URL and redirect URLs at your Vercel domain.

Deploy on Netlify

Before closing out a release, follow docs/DEPLOY_CHECKLIST.md (commit/push → confirm Netlify commit → curl route health).

  1. In the site’s Environment variables, set NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY for your Supabase project.
  2. If NEXT_PUBLIC_SUPABASE_ANON_KEY might be wrong or from another project, remove it. The app uses publishable first when it is non-empty, but deleting a bad anon avoids confusion and mistaken “which key is live?” during rollouts.
  3. Run Deploys → Clear cache and deploy site after any NEXT_PUBLIC_* change so the new values are inlined into the client bundle.
  4. After deploy, hard refresh the site and sign in again so session cookies match the deployed URL and keys.

From the repo you can also use npm run netlify:deploy:prod (see Netlify CLI); env vars are still managed in the Netlify UI or via npm run ntl -- env:set … when authenticated.

Scripts

CommandDescription
npm run devDev server
npm run buildProduction build
npm run startStart production
npm run lintESLint
npm run testVitest (AI schema)

Product disclaimer

DeenNotes is for organizing Islamic learning and personal reflection. It does not provide fatwas or religious rulings. Users should consult a qualified scholar or imam for religious decisions.

About

AI Islamic reflection journal for khutbah notes, lectures, duas, and weekly action steps.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages