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
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "tsx src/index.ts",
"build": "prisma generate && tsc",
"postinstall": "[ -f prisma/schema.prisma ] && prisma generate || true"
"postinstall": "node -e \"const fs = require('fs'); if (fs.existsSync('prisma/schema.prisma')) { require('child_process').execSync('prisma generate', { stdio: 'inherit' }); }\""
},
"keywords": [],
"author": "Ajeet Pratpa Singh",
Expand Down
Empty file added apps/api/prisma/dev.db
Empty file.
2 changes: 1 addition & 1 deletion apps/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ generator client {
}

datasource db {
provider = "postgresql"
provider = "sqlite"
url = env("DATABASE_URL")
}

Expand Down
18 changes: 9 additions & 9 deletions apps/api/src/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,38 +23,38 @@ const basePrisma = new PrismaClient({
const prisma = basePrisma.$extends({
query: {
account: {
async create({ args, query }) {
async create({ args, query }: any) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the file
ls -la apps/api/src/prisma.ts

# Show the relevant sections around the referenced lines
nl -ba apps/api/src/prisma.ts | sed -n '1,140p'

# Find any ": any" occurrences in prisma.ts
rg -n ": any" apps/api/src/prisma.ts || true

# Show additional occurrences across apps/api/src if needed
rg -n ": any" apps/api/src/prisma.ts apps/api/src -S --glob='**/*.ts' | head -n 200

Repository: apsinghdev/opensox

Length of output: 195


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ls -la apps/api/src/prisma.ts

# Print first 140 lines with line numbers (avoid nl)
awk '{printf "%4d:%s\n", NR, $0}' apps/api/src/prisma.ts | sed -n '1,140p'

# Find any ": any" occurrences in prisma.ts
rg -n ": any" apps/api/src/prisma.ts || true

Repository: apsinghdev/opensox

Length of output: 4984


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# show encryption util
ls -la apps/api/src/utils/encryption.js apps/api/src/utils/encryption.ts 2>/dev/null || true
sed -n '1,200p' apps/api/src/utils/encryption.js 2>/dev/null || true

# also search for encrypt/decrypt function definitions/usages
rg -n "function (encryptAccountTokens|decryptAccountTokens)|const (encryptAccountTokens|decryptAccountTokens)" apps/api/src/utils -S || true
rg -n "encryptAccountTokens|decryptAccountTokens" apps/api/src -S --glob='**/*.ts' --glob='**/*.js' | head -n 200

Repository: apsinghdev/opensox

Length of output: 1764


remove any in prisma extension callback types

apps/api/src/prisma.ts introduces : any on the prisma extension middleware signatures (create/update/upsert/findUnique/findFirst/findMany) and also uses account: any / user: any in .map(...) callbacks (lines 26, 31, 36, 42, 46, 50, 57, 68, 79). this bypasses type safety on critical db query paths.

apps/api/src/utils/encryption.ts also types encryptAccountTokens/decryptAccountTokens as (data: any) => any (lines 100, 144), which prevents fully eliminating any downstream.

proposed fix
-      async create({ args, query }: any) {
+      async create({ args, query }) {
...
-      async update({ args, query }: any) {
+      async update({ args, query }) {
...
-      async upsert({ args, query }: any) {
+      async upsert({ args, query }) {
...
-      async findUnique({ args, query }: any) {
+      async findUnique({ args, query }) {
...
-      async findFirst({ args, query }: any) {
+      async findFirst({ args, query }) {
...
-      async findMany({ args, query }: any) {
+      async findMany({ args, query }) {
...
-      async findUnique({ args, query }: any) {
+      async findUnique({ args, query }) {
...
-      async findFirst({ args, query }: any) {
+      async findFirst({ args, query }) {
...
-      async findMany({ args, query }: any) {
+      async findMany({ args, query }) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/prisma.ts` at line 26, Replace all uses of the unsafe any in the
Prisma extension callbacks and map callbacks with proper types: import Prisma
types from '`@prisma/client`' and type the extension callback parameters (replace
"{ args, query }: any" in create/update/upsert/findUnique/findFirst/findMany)
using Prisma.MiddlewareParams (or the specific delegate arg types provided by
your Prisma version) and the Prisma client/query return types instead of any;
replace map callback parameters "account: any" / "user: any" with the generated
model types (import type { Account, User } from '`@prisma/client`') so map
callbacks use Account/User; and change encryptAccountTokens/decryptAccountTokens
signatures from (data: any) => any to explicit input/output types (e.g., (data:
AccountTokens) => EncryptedAccountTokens or a concrete Record shape) and
propagate those types to callers so no downstream any remains. Ensure you import
the required types and update all occurrences of these symbols
(create/update/upsert/findUnique/findFirst/findMany, account, user,
encryptAccountTokens, decryptAccountTokens) accordingly.

args.data = encryptAccountTokens(args.data);
const result = await query(args);
return decryptAccountTokens(result);
},
async update({ args, query }) {
async update({ args, query }: any) {
args.data = encryptAccountTokens(args.data);
const result = await query(args);
return decryptAccountTokens(result);
},
async upsert({ args, query }) {
async upsert({ args, query }: any) {
args.create = encryptAccountTokens(args.create);
args.update = encryptAccountTokens(args.update);
const result = await query(args);
return decryptAccountTokens(result);
},
async findUnique({ args, query }) {
async findUnique({ args, query }: any) {
const result = await query(args);
return decryptAccountTokens(result);
},
async findFirst({ args, query }) {
async findFirst({ args, query }: any) {
const result = await query(args);
return decryptAccountTokens(result);
},
async findMany({ args, query }) {
async findMany({ args, query }: any) {
const result = await query(args);
return result?.map((account: any) => decryptAccountTokens(account));
},
},
user: {
// Decrypt nested accounts in user queries
async findUnique({ args, query }) {
async findUnique({ args, query }: any) {
const result = await query(args);
if (result?.accounts) {
result.accounts = Array.isArray(result.accounts)
Expand All @@ -65,7 +65,7 @@ const prisma = basePrisma.$extends({
}
return result;
},
async findFirst({ args, query }) {
async findFirst({ args, query }: any) {
const result = await query(args);
if (result?.accounts) {
result.accounts = Array.isArray(result.accounts)
Expand All @@ -76,7 +76,7 @@ const prisma = basePrisma.$extends({
}
return result;
},
async findMany({ args, query }) {
async findMany({ args, query }: any) {
const result = await query(args);
return result?.map((user: any) => {
if (user?.accounts) {
Expand Down
14 changes: 10 additions & 4 deletions apps/web/src/app/(main)/(landing)/pricing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ const Pricing = () => {
</div>
</div>
</div>
<div className="relative border-b border-[#252525] lg:pb-10">
<div className="flex flex-col gap-5 lg:gap-10 py-4 bg-[#151515]/20 backdrop-blur-xl h-full relative w-full overflow-hidden px-4 lg:px-10">
<div className="relative border-b border-[#252525] lg:pb-10 isolate" style={{ contain: 'layout paint' }}>
<div className="flex flex-col gap-5 lg:gap-10 py-4 bg-[#151515]/20 h-full relative w-full overflow-hidden px-4 lg:px-10">
Comment on lines +373 to +374
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

replace inline contain style with design-system-compatible utility usage

this adds inline style on a web component, which conflicts with the styling rule for this path. please move this to tailwind/design-token-based styling.

as per coding guidelines "always use tailwind classes for styling html elements; avoid using css or style tags".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/app/`(main)/(landing)/pricing/page.tsx around lines 373 - 374,
The div in page.tsx currently uses an inline style "style={{ contain: 'layout
paint' }}" which must be replaced with a design-system/Tailwind-compatible
utility; remove the inline style from the element with class "relative border-b
border-[`#252525`] lg:pb-10 isolate" and instead add a named utility (e.g.,
.contain-layout-paint or a Tailwind plugin/arbitrary utility) in the shared
design-system CSS/Tailwind config that emits "contain: layout paint", ensure the
class is available to the app (imported or safelisted), and then apply that
utility class (e.g., "contain-layout-paint") to the same div so all styling uses
Tailwind/design tokens rather than inline styles.

<div className="absolute inset-0 -top-72">
<Image
src="/assets/layer1.svg"
Expand Down Expand Up @@ -487,7 +487,10 @@ const PricingCard = () => {
})}
</div>
</div>
<div className="bg-white mix-blend-plus-lighter absolute h-[120px] w-full blur-[60px] right-0 -bottom-20 opacity-80"></div>
<div
className="absolute h-[250px] w-[150%] left-1/2 -translate-x-1/2 -bottom-24 opacity-60 pointer-events-none"
style={{ background: 'radial-gradient(ellipse at center, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 60%)' }}
></div>
Comment on lines +490 to +493
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

avoid duplicated inline radial gradients with hardcoded color values

both glow overlays use duplicated inline gradient strings and hardcoded color values. extract a reusable class/component and use semantic design-token colors via tailwind utilities.

as per coding guidelines "never use hardcoded hex values directly in components; always reference colors from the design token system using tailwind classes".

Also applies to: 647-650

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/app/`(main)/(landing)/pricing/page.tsx around lines 490 - 493,
The inline radial-gradient with hardcoded rgba values in the glow overlay div
should be extracted into a reusable component or utility (e.g., GlowOverlay) and
the gradient must be implemented using Tailwind design-token colors instead of
literal hex/rgba; replace the style prop on the element with a class (or
component) that references a custom Tailwind class/variant defined in your
tailwind config or global css that composes a radial-gradient using design
tokens (token names from your color palette), then replace both occurrences (the
current div with className "absolute h-[250px] w-[150%] left-1/2
-translate-x-1/2 -bottom-24 opacity-60 pointer-events-none" and the duplicate
overlay later) to use that reusable class/component.

</div>
</div>
</div>
Expand Down Expand Up @@ -641,7 +644,10 @@ const SecondaryPricingCard = ({ callbackUrl }: { callbackUrl: string }) => {
})}
</div>
</div>
<div className="bg-white mix-blend-plus-lighter absolute h-[120px] w-full blur-[60px] right-0 -bottom-20 opacity-80"></div>
<div
className="absolute h-[250px] w-[150%] left-1/2 -translate-x-1/2 -bottom-24 opacity-60 pointer-events-none"
style={{ background: 'radial-gradient(ellipse at center, rgba(255,255,255,0.6) 0%, rgba(255,255,255,0) 60%)' }}
></div>
</div>
</div>
</div>
Expand Down
45 changes: 40 additions & 5 deletions apps/web/src/components/ui/flickering-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,14 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({

const updateSquares = useCallback(
(squares: Float32Array, deltaTime: number) => {
const updatedIndices: number[] = [];
for (let i = 0; i < squares.length; i++) {
if (Math.random() < flickerChance * deltaTime) {
squares[i] = Math.random() * maxOpacity;
updatedIndices.push(i);
}
}
return updatedIndices;
},
[flickerChance, maxOpacity],
);
Expand Down Expand Up @@ -114,6 +117,30 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
[memoizedColor, squareSize, gridGap],
);

const drawUpdatedSquares = useCallback(
(
ctx: CanvasRenderingContext2D,
rows: number,
squares: Float32Array,
dpr: number,
updatedIndices: number[],
) => {
for (const idx of updatedIndices) {
const i = Math.floor(idx / rows);
const j = idx % rows;
const opacity = squares[idx];
const x = i * (squareSize + gridGap) * dpr;
const y = j * (squareSize + gridGap) * dpr;
const size = squareSize * dpr;

ctx.clearRect(x, y, size, size);
ctx.fillStyle = `${memoizedColor}${opacity})`;
ctx.fillRect(x, y, size, size);
}
},
[memoizedColor, squareSize, gridGap],
);

useEffect(() => {
const canvas = canvasRef.current;
const container = containerRef.current;
Expand All @@ -130,6 +157,16 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
const newHeight = height || container.clientHeight;
setCanvasSize({ width: newWidth, height: newHeight });
gridParams = setupCanvas(canvas, newWidth, newHeight);

drawGrid(
ctx,
canvas.width,
canvas.height,
gridParams.cols,
gridParams.rows,
gridParams.squares,
gridParams.dpr,
);
};

updateCanvasSize();
Expand All @@ -141,15 +178,13 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
const deltaTime = (time - lastTime) / 1000;
lastTime = time;

updateSquares(gridParams.squares, deltaTime);
drawGrid(
const updatedIndices = updateSquares(gridParams.squares, deltaTime);
drawUpdatedSquares(
ctx,
canvas.width,
canvas.height,
gridParams.cols,
gridParams.rows,
gridParams.squares,
gridParams.dpr,
updatedIndices
);
animationFrameId = requestAnimationFrame(animate);
};
Expand Down
74 changes: 53 additions & 21 deletions apps/web/src/components/ui/shine-borders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,59 @@ export function ShineBorder({
style,
...props
}: ShineBorderProps) {
const containerRef = React.useRef<HTMLDivElement>(null);
const [isVisible, setIsVisible] = React.useState(true);

React.useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setIsVisible(entry.isIntersecting);
},
{ rootMargin: "150px" }
);
if (containerRef.current) observer.observe(containerRef.current);
return () => observer.disconnect();
}, []);

const gradientColor = Array.isArray(shineColor) ? shineColor.join(",") : shineColor;

return (
<div
style={
{
"--border-width": `${borderWidth}px`,
"--duration": `${duration}s`,
backgroundImage: `radial-gradient(transparent,transparent, ${Array.isArray(shineColor) ? shineColor.join(",") : shineColor},transparent,transparent)`,
backgroundSize: "300% 300%",
mask: `linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)`,
WebkitMask: `linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)`,
WebkitMaskComposite: "xor",
maskComposite: "exclude",
padding: "var(--border-width)",
...style,
} as React.CSSProperties
}
className={cn(
"pointer-events-none absolute inset-0 size-full rounded-[inherit] will-change-[background-position] motion-safe:animate-shine",
className,
)}
{...props}
/>
<>
<style>{`
@keyframes shine-transform {
0% { transform: translate(-33.33%, -33.33%); }
50% { transform: translate(33.33%, 33.33%); }
100% { transform: translate(-33.33%, -33.33%); }
}
`}</style>
Comment on lines +55 to +62
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

move keyframes/animation styling out of component-local style tag

injecting @keyframes inside each component instance and driving animation via inline style is not aligned with the web styling rules here. define the animation in tailwind/config or shared stylesheet and toggle with classes.

as per coding guidelines "always use tailwind classes for styling html elements; avoid using css or style tags".

Also applies to: 84-88

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/ui/shine-borders.tsx` around lines 55 - 62, The
component currently injects the `@keyframes` "shine-transform" and uses inline
animation styles inside the JSX fragment (see the style tag in shine-borders.tsx
and the similar block around lines 84-88); move that keyframes/animation
definition into a shared stylesheet or add it to the Tailwind config as a custom
animation (e.g., extend theme.animation/keyframes), remove the <style> tag and
any inline style animation properties in the component, and instead toggle the
animation with Tailwind utility classes or a custom class (referencing the
"shine-transform" name when you add it to Tailwind) so the component uses
classes only for styling.

<div
ref={containerRef}
style={
{
"--border-width": `${borderWidth}px`,
mask: `linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)`,
WebkitMask: `linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)`,
WebkitMaskComposite: "xor",
maskComposite: "exclude",
padding: "var(--border-width)",
...style,
} as React.CSSProperties
}
className={cn(
"pointer-events-none absolute inset-0 size-full rounded-[inherit] overflow-hidden",
className,
)}
{...props}
>
<div
className="absolute inset-0 w-[300%] h-[300%] -left-[100%] -top-[100%] will-change-transform transform-gpu"
style={{
backgroundImage: `radial-gradient(transparent, transparent, ${gradientColor}, transparent, transparent)`,
animation: `shine-transform ${duration}s infinite linear`,
animationPlayState: isVisible ? "running" : "paused",
}}
/>
</div>
</>
);
}