fix: core api#105
Conversation
WalkthroughAdds a public runtime config key for the core API URL and an env example, introduces a server POST proxy endpoint for comment beaconing, updates components to use the runtime config or local proxy (removing some toast usage), and expands accepted image MIME/formats to include AVIF and HEIF. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as CreateEpicCommentBeacon.vue
participant N as Nuxt Server (/api/.../beacon)
participant CORE as Core API
C->>N: POST /api/epic/comment/id/{commentId}/beacon\npayload
N->>N: Validate body (createBeaconSchema)\nExtract commentId
alt valid & commentId present
N->>CORE: POST {publicEnv.coreApiUrl}/epic/comment/id/{commentId}/beacon\nvalidated payload
CORE-->>N: 200 OK
N-->>C: { ok: true }
note right of C: emit success, vibrate
else validation / missing id
N-->>C: 400 / validation error (via errorResolver)
note right of C: emit error, vibrate
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
apps/atrium-telegram/app/app.vue (1)
7-7: Consider safe-area-aware top offset for toasterOn some devices/Telegram WebView, fixed top toasts can overlap the OS/Telegram bars. Prefer a safe-area-aware offset (or compute offset in CSS) instead of a hard
mt-20.Would you like me to propose a tiny CSS utility that uses
env(safe-area-inset-top)?apps/atrium-telegram/.env.example (1)
4-6: Document expected format and sample valueAdd a concrete example and note “no trailing slash” to avoid
//joins.-# Main API -NUXT_CORE_API_URL= +# Main API (no trailing slash), e.g. https://core.example.com +NUXT_CORE_API_URL=https://core.example.com
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
apps/atrium-telegram/.env.example(1 hunks)apps/atrium-telegram/app/app.vue(1 hunks)apps/atrium-telegram/app/components/form/CreateEpicCommentBeacon.vue(1 hunks)apps/atrium-telegram/nuxt.config.ts(1 hunks)apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (3)
apps/atrium-telegram/nuxt.config.ts (1)
27-27: Runtime config: verify env mapping and keep it privateGood to keep
coreApiUrlprivate. Please verifyNUXT_CORE_API_URLactually maps toruntimeConfig.coreApiUrlin your setup; Nuxt’s env-to-config mapping can be subtle. If there’s any doubt, add a dev-time assertion (or log) and fail fast when empty.Apply guard in the proxy route (see related comment) to prevent silent 404/loops when
coreApiUrlis unset.apps/atrium-telegram/app/components/form/CreateEpicCommentBeacon.vue (1)
98-101: Switch to internal endpoint looks goodRouting via the Nuxt server endpoint is the right move; cookies will flow and CORS is avoided.
apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts (1)
14-18: Validation check with arktype is likely incorrect; assert or check issues instead
instanceof type.errorsis not a reliable pattern here and can silently pass invalid data. Prefer asserting or inspectingissues.Proposed (Option A – assert and drop the extra import):
-import { type } from 'arktype' @@ - const body = await readBody(event) - const data = createBeaconSchema(body) - if (data instanceof type.errors) { - throw data - } + const body = await readBody(event) + // Throws on invalid and returns typed data on success + const data = createBeaconSchema.assert(body)Alternative (Option B – safe-check):
- const body = await readBody(event) - const data = createBeaconSchema(body) - if (data instanceof type.errors) { - throw data - } + const body = await readBody(event) + const parsed = createBeaconSchema(body) + if (parsed?.issues) { + throw createError({ statusCode: 400, message: parsed?.summary ?? 'Invalid payload' }) + } + const data = parsedLikely an incorrect or invalid review comment.
| const body = await readBody(event) | ||
| const data = createBeaconSchema(body) | ||
| if (data instanceof type.errors) { | ||
| throw data | ||
| } | ||
|
|
||
| const { coreApiUrl } = useRuntimeConfig() | ||
|
|
||
| await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, { | ||
| method: 'POST', | ||
| body: data, | ||
| }) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Don’t trust client-provided senderId; derive server-side
CreateBeacon includes senderId. The client sets it from userStore.id, which a malicious client can spoof. Server should derive senderId from the authenticated session and either overwrite or drop the field before forwarding.
- const data = createBeaconSchema.assert(body)
+ const data = createBeaconSchema.assert(body)
+ // Example: enforce from auth (adjust getter to your auth layer)
+ const currentUserId = event.context?.auth?.user?.id
+ if (currentUserId) {
+ // Overwrite or ensure parity
+ // @ts-expect-error - narrow type if needed
+ data.senderId = currentUserId
+ } else {
+ // Optionally fail if unauthenticated
+ throw createError({ statusCode: 401, message: 'Unauthorized' })
+ }If core API already ignores/overwrites senderId, confirm and we can simply delete (data as any).senderId before forwarding.
🏁 Script executed:
#!/bin/bash
set -e
# Search for createBeaconSchema definition and usages
rg -n "createBeaconSchema" --glob "*.ts" -C3Length of output: 3588
Enforce server-side senderId
Derive senderId from the authenticated session and never trust client input. For example:
const body = await readBody(event)
- const data = createBeaconSchema(body)
+ const data = createBeaconSchema(body)
if (data instanceof type.errors) throw data
+ const currentUserId = event.context.auth?.user?.id
+ if (!currentUserId) throw createError({ statusCode: 401, message: 'Unauthorized' })
+ const payload = { senderId: currentUserId, usersId: data.usersId }
const { coreApiUrl } = useRuntimeConfig()
- await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, {
- method: 'POST',
- body: data,
- })
+ await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, {
+ method: 'POST',
+ body: payload,
+ })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const body = await readBody(event) | |
| const data = createBeaconSchema(body) | |
| if (data instanceof type.errors) { | |
| throw data | |
| } | |
| const { coreApiUrl } = useRuntimeConfig() | |
| await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, { | |
| method: 'POST', | |
| body: data, | |
| }) | |
| const body = await readBody(event) | |
| const data = createBeaconSchema(body) | |
| if (data instanceof type.errors) { | |
| throw data | |
| } | |
| // Derive senderId from authenticated session | |
| const currentUserId = event.context.auth?.user?.id | |
| if (!currentUserId) throw createError({ statusCode: 401, message: 'Unauthorized' }) | |
| const payload = { senderId: currentUserId, usersId: data.usersId } | |
| const { coreApiUrl } = useRuntimeConfig() | |
| await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, { | |
| method: 'POST', | |
| body: payload, | |
| }) |
🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts
around lines 14–25, the code currently uses client-supplied senderId; instead
derive senderId from the authenticated session, reject requests with no
authenticated user, and never trust or pass through a client-sent senderId.
Retrieve the authenticated user id from the server session/context,
merge/overwrite data.senderId = sessionUserId (or return 401 if missing) before
any schema creation/validation or before sending to core, and ensure the schema
used for createBeaconSchema does not accept or persist a client-provided
senderId (or validate after you overwrite it) so the forwarded POST to core
contains the server-derived senderId only.
| const { coreApiUrl } = useRuntimeConfig() | ||
|
|
||
| await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, { | ||
| method: 'POST', | ||
| body: data, | ||
| }) |
There was a problem hiding this comment.
Harden proxy: guard missing base URL, normalize URL, forward auth, set timeout
- Fail fast if
coreApiUrlis empty. - Normalize join to avoid
//. - Forward
authorization/cookieso the core API can authenticate. - Add a reasonable timeout and avoid retries.
- const { coreApiUrl } = useRuntimeConfig()
-
- await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, {
- method: 'POST',
- body: data,
- })
+ const { coreApiUrl } = useRuntimeConfig()
+ if (!coreApiUrl) {
+ throw createError({ statusCode: 500, message: 'coreApiUrl is not configured' })
+ }
+
+ const auth = getHeader(event, 'authorization')
+ const cookie = getHeader(event, 'cookie')
+
+ await $fetch(`${coreApiUrl.replace(/\/+$/, '')}/epic/comment/id/${commentId}/beacon`, {
+ method: 'POST',
+ body: data,
+ headers: {
+ ...(auth ? { authorization: auth } : {}),
+ ...(cookie ? { cookie } : {}),
+ },
+ timeout: 10_000,
+ retry: 0,
+ })📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { coreApiUrl } = useRuntimeConfig() | |
| await $fetch(`${coreApiUrl}/epic/comment/id/${commentId}/beacon`, { | |
| method: 'POST', | |
| body: data, | |
| }) | |
| const { coreApiUrl } = useRuntimeConfig() | |
| if (!coreApiUrl) { | |
| throw createError({ statusCode: 500, message: 'coreApiUrl is not configured' }) | |
| } | |
| const auth = getHeader(event, 'authorization') | |
| const cookie = getHeader(event, 'cookie') | |
| await $fetch(`${coreApiUrl.replace(/\/+$/, '')}/epic/comment/id/${commentId}/beacon`, { | |
| method: 'POST', | |
| body: data, | |
| headers: { | |
| ...(auth ? { authorization: auth } : {}), | |
| ...(cookie ? { cookie } : {}), | |
| }, | |
| timeout: 10_000, | |
| retry: 0, | |
| }) |
| } catch (error) { | ||
| throw errorResolver(error) | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Ensure errorResolver is available/imported
errorResolver isn’t a Nitro/H3 builtin. If not globally auto-imported, this will throw at runtime. Please verify and add an explicit import if needed.
Run to locate its definition:
If it lives under a util path, import it explicitly at the top of this file.
🏁 Script executed:
#!/bin/bash
rg -nP -C2 '\b(errorResolver)\b' --type=ts --type=jsLength of output: 44144
🏁 Script executed:
#!/bin/bash
head -n 20 apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.tsLength of output: 620
Import errorResolver at the top of beacon.post.ts
This handler calls errorResolver (from apps/atrium-telegram/server/utils/error.ts) but never imports it. Add, for example, immediately after the existing imports:
import { errorResolver } from '../../../../../utils/error'—adjust the relative path or alias to match your project’s resolver.
🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts
around lines 30 to 32 the file uses errorResolver but never imports it; add an
import for errorResolver from the utils/error module at the top of the file (for
example: import { errorResolver } from '../../../../../utils/error') or adjust
the path/alias to match the project, then ensure the import is included with the
other imports so the catch block can call errorResolver without a
ReferenceError.
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web-app/server/api/user/id/[userId]/image.post.ts (1)
96-104: Use sharp.clone() per rendition; fix typing; remove manual nulling.Reusing the same Sharp instance across iterations risks transform carryover and unnecessary mutation. Also don’t type the buffer as unknown.
Apply:
- let buffer: unknown = await sharpStream - .resize({ width: size, height: size }) - .toFormat(format, { quality: 90 }) - .toBuffer() + const buffer: Buffer = await sharpStream + .clone() + .rotate() // honor EXIF orientation + .resize({ width: size, height: size }) + .toFormat(format, { quality: 90 }) + .toBuffer() @@ - // Clear - buffer = nullAlso applies to: 113-115
🧹 Nitpick comments (2)
apps/web-app/shared/services/media.ts (1)
4-12: Deduplicate accepted image type lists across apps.This list is duplicated in multiple apps; drift is likely. Extract to a shared module (e.g., packages/shared-media) and import in both places.
apps/atrium-telegram/app/components/form/UploadUserAvatar.vue (1)
69-71: Guard against double slashes in coreApiUrl.If coreApiUrl ends with '/', the URL may contain '//'. Harmless for most CDNs, but can break signed URLs. Consider joinURL from ufo or trimEnd('/').
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
apps/atrium-telegram/.env.example(1 hunks)apps/atrium-telegram/app/components/form/UploadUserAvatar.vue(1 hunks)apps/atrium-telegram/nuxt.config.ts(1 hunks)apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts(1 hunks)apps/atrium-telegram/shared/services/media.ts(1 hunks)apps/web-app/server/api/user/id/[userId]/image.post.ts(1 hunks)apps/web-app/shared/services/media.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/atrium-telegram/nuxt.config.ts
- apps/atrium-telegram/.env.example
- apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
| const { public: publicEnv } = useRuntimeConfig() | ||
|
|
||
| await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, { | ||
| method: 'POST', | ||
| headers: { | ||
| Authorization: `tma ${userStore.initDataRaw}`, | ||
| }, | ||
| body: formData, | ||
| }) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Auth regression: cross-origin request sends no credentials.
Switching to coreApiUrl without Authorization or credentials will 401. Either route via a local proxy endpoint or include credentials.
Apply minimal fix:
- await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, {
+ await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, {
method: 'POST',
body: formData,
+ credentials: 'include',
})If cookies aren’t first-party to coreApiUrl, prefer a Nuxt server proxy (e.g., POST /api/user/id/[id]/image) to avoid CORS + cookies pitfalls.
🏁 Script executed:
#!/bin/bash
# Confirm no remaining direct calls to core API that need credentials
rg -nP --type=vue --type=ts '\$\s*fetch\(\s*`?\${?publicEnv\.coreApiUrl' -C2Length of output: 106
🏁 Script executed:
#!/bin/bash
# Confirm no other direct $fetch calls to coreApiUrl without credentials
rg -nP '\$fetch\(\s*`.*publicEnv\.coreApiUrl' -C2 --glob '*.vue'
rg -nP '\$fetch\(\s*`.*publicEnv\.coreApiUrl' -C2 --glob '*.ts'Length of output: 1197
Auth regression: include credentials or proxy for all coreApiUrl fetch calls
Two direct $fetch calls to publicEnv.coreApiUrl lack credentials/authorization and will 401:
- apps/atrium-telegram/app/components/form/UploadUserAvatar.vue (lines 69–72)
- apps/atrium-telegram/server/api/epic/comment/id/[commentId]/beacon.post.ts (lines 22–24)
Apply minimal fixes:
# File: UploadUserAvatar.vue
await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, {
method: 'POST',
body: formData,
+ credentials: 'include',
})
# File: beacon.post.ts
await $fetch(`${publicEnv.coreApiUrl}/epic/comment/id/${commentId}/beacon`, {
method: 'POST',
body: data,
+ credentials: 'include',
})If cookies aren’t first-party to coreApiUrl, route client calls via a Nuxt server proxy endpoint to avoid CORS and cookie pitfalls.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { public: publicEnv } = useRuntimeConfig() | |
| await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, { | |
| method: 'POST', | |
| headers: { | |
| Authorization: `tma ${userStore.initDataRaw}`, | |
| }, | |
| body: formData, | |
| }) | |
| const { public: publicEnv } = useRuntimeConfig() | |
| await $fetch(`${publicEnv.coreApiUrl}/user/id/${userStore.id}/image`, { | |
| method: 'POST', | |
| body: formData, | |
| credentials: 'include', | |
| }) |
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/form/UploadUserAvatar.vue around lines 67
to 72, the client $fetch to publicEnv.coreApiUrl is missing credentials and will
401; either add credentials to the client request (e.g., pass credentials:
"include" / appropriate auth headers via useFetch/$fetch options) or, if
coreApiUrl cookies are not first‑party, replace the direct call with a Nuxt
server proxy endpoint: create a server API route that receives the form data
from the client and forwards the POST to coreApiUrl including server-side
cookies/authorization, then call that internal endpoint from the component.
Ensure the chosen fix propagates formData correctly and handles/forwards errors.
| 'image/avif', | ||
| 'image/heif', |
There was a problem hiding this comment.
Add image/heic to accepted MIME types (iOS default).
Mirror the web-app change; otherwise HEIC uploads from iOS will be rejected client-side.
Apply:
'image/gif',
'image/avif',
'image/heif',
+ 'image/heic',
]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 'image/avif', | |
| 'image/heif', | |
| 'image/gif', | |
| 'image/avif', | |
| 'image/heif', | |
| 'image/heic', | |
| ] |
🤖 Prompt for AI Agents
In apps/atrium-telegram/shared/services/media.ts around lines 10 to 11, the
accepted MIME types array is missing 'image/heic' (iOS default) which causes
HEIC uploads to be rejected; add the string 'image/heic' to the list of accepted
MIME types (e.g., alongside 'image/heif' and 'image/avif') so the client will
allow HEIC images.
| const IMAGE_SIZES = [256, 512] | ||
| const IMAGE_FORMATS = ['jpg', 'webp'] as const | ||
| const ACCEPTED_IMAGE_FORMATS = ['jpeg', 'jpg', 'png', 'webp'] | ||
| const ACCEPTED_IMAGE_FORMATS = ['jpeg', 'jpg', 'png', 'webp', 'heif', 'avif'] |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Include ‘heic’ and confirm runtime decode support.
- Add 'heic' for broader HEIF coverage.
- Ensure the deployment’s sharp/libvips build supports HEIF/AVIF decode; otherwise uploads will fail at metadata().
Apply:
-const ACCEPTED_IMAGE_FORMATS = ['jpeg', 'jpg', 'png', 'webp', 'heif', 'avif']
+const ACCEPTED_IMAGE_FORMATS = ['jpeg', 'jpg', 'png', 'webp', 'heif', 'heic', 'avif'] as constTo verify support and avoid regressions, run:
And confirm environment support:
🏁 Script executed:
#!/bin/bash
# Find all places that mention HEIF/AVIF and ensure consistency
rg -nC2 -i 'heif|heic|avif|ACCEPTED_IMAGE_FORMATS|ACCEPTED_IMAGE_TYPES'
# Optional: check sharp version used (lockfile)
fd lock | xargs -I{} rg -n 'sharp@' {}Length of output: 5647
🌐 Web query:
Does the current sharp version used by Nuxt/Nitro support decoding HEIF/HEIC and AVIF by default, or does it require libvips/OS dependencies?
💡 Result:
Short answer: You still need libvips / OS libs for full HEIF/HEIC (HEVC) support; AVIF is supported by sharp’s prebuilt binaries. sharp’s docs/state that AVIF is included in prebuilt binaries, but HEIF/HEIC using HEVC requires a globally installed libvips compiled with libheif (and codecs like libde265/x265). [1][2]
Sources:
- sharp API (HEIF notes). [1]
- sharp changelog (AVIF/prebuilt binaries; HEIF requires libvips compiled with libheif). [2]
Add HEIC support and verify HEIF/HEIC decode dependencies
- Update
apps/web-app/server/api/user/id/[userId]/image.post.ts(line 10): include'heic'inACCEPTED_IMAGE_FORMATS(e.g.['jpeg','jpg','png','webp','heif','heic','avif']) and consider appendingas const. - Mirror in
apps/web-app/shared/services/media.ts(line 10): add'image/heic'toACCEPTED_IMAGE_TYPES. - Confirm your deployment’s libvips build is compiled with libheif and HEVC codecs (sharp’s prebuilt binaries include AVIF but not full HEIF/HEIC support).
🤖 Prompt for AI Agents
In apps/web-app/server/api/user/id/[userId]/image.post.ts around line 10, add
'heic' to ACCEPTED_IMAGE_FORMATS (e.g.
['jpeg','jpg','png','webp','heif','heic','avif']) and consider marking the array
as readonly (as const); in apps/web-app/shared/services/media.ts around line 10,
add 'image/heic' to ACCEPTED_IMAGE_TYPES to mirror the change; finally, ensure
your deployment's libvips/sharp build includes libheif and required HEVC codecs
(or document fallback behavior) because sharp’s prebuilt binaries may not
provide full HEIF/HEIC support.
| 'image/avif', | ||
| 'image/heif', |
There was a problem hiding this comment.
Add image/heic to accepted MIME types (iOS default).
Many devices (notably iOS) upload HEIC as image/heic; current schema will reject them.
Apply:
'image/gif',
'image/avif',
'image/heif',
+ 'image/heic',
]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 'image/avif', | |
| 'image/heif', | |
| 'image/gif', | |
| 'image/avif', | |
| 'image/heif', | |
| 'image/heic', | |
| ] |
🤖 Prompt for AI Agents
In apps/web-app/shared/services/media.ts around lines 10-11 the accepted MIME
types list is missing the iOS default 'image/heic', so uploads from many iOS
devices will be rejected; add 'image/heic' to the array of accepted MIME types
alongside the existing image/avif and image/heif entries, and run/update any
related validation/schema tests or type definitions that reference this list to
include the new value.



Summary by CodeRabbit