diff --git a/controllers/admin/advertisements.controller.js b/controllers/admin/advertisements.controller.js index 4f270e8..9ce22fd 100644 --- a/controllers/admin/advertisements.controller.js +++ b/controllers/admin/advertisements.controller.js @@ -122,7 +122,7 @@ async function applyAdvertisementFields(advertisement, body) { } else { const asset = await mdl_Assets.findOne({ where: { asset_id: body.image_asset_id, deletedAt: null } }); if (!asset) { - const err = new Error("Selected image asset was not found."); + const err = new Error("Selected image file was not found."); err.status = 400; throw err; } diff --git a/controllers/admin/assets.controller.js b/controllers/admin/assets.controller.js index fe5f9d1..13e90ef 100644 --- a/controllers/admin/assets.controller.js +++ b/controllers/admin/assets.controller.js @@ -245,10 +245,10 @@ exports.getAssets = async (req, res) => { } const data = await attachStreamTokens(result.data, req); - return R.success(res, "Assets retrieved.", { ...result, data }); + return R.success(res, "Files retrieved.", { ...result, data }); } catch (err) { console.error("[ASSET][GET ALL]", err); - return R.error(res, "Could not retrieve assets.", 500); + return R.error(res, "Could not retrieve files.", 500); } }; @@ -257,7 +257,7 @@ exports.getAssets = async (req, res) => { exports.getAsset = async (req, res) => { try { const { assetId } = req.params; - if (!assetId || assetId === "undefined") return R.error(res, "Invalid asset ID.", 400); + if (!assetId || assetId === "undefined") return R.error(res, "Invalid file ID.", 400); const asset = await Asset.findOne({ where: { asset_id: assetId, ...notDeleted }, @@ -270,7 +270,7 @@ exports.getAsset = async (req, res) => { ], }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); const json = asset.toJSON(); @@ -298,7 +298,7 @@ exports.getAsset = async (req, res) => { delete json.storage_key; redactS3Url(json); - return R.success(res, "Asset retrieved.", { data: json }); + return R.success(res, "File retrieved.", { data: json }); } catch (err) { console.error("[ASSET][GET ONE]", err); return R.error(res, "Internal server error.", 500); @@ -578,7 +578,7 @@ exports.uploadAsset = async (req, res) => { const { storage_key, thumbnail_storage_key, original_name } = req.body; const asset = await finalizeAssetFromStorage({ storage_key, thumbnail_storage_key, original_name, body: req.body, user: req.user }); invalidateListCache(); - return R.success(res, "Asset uploaded.", { data: asset }, 201); + return R.success(res, "File uploaded.", { data: asset }, 201); } catch (err) { console.error("[ASSET][UPLOAD]", err); @@ -594,10 +594,10 @@ exports.updateAsset = async (req, res) => { try { const { assetId } = req.params; - if (!assetId || assetId === "undefined") return R.error(res, "Invalid asset ID.", 400); + if (!assetId || assetId === "undefined") return R.error(res, "Invalid file ID.", 400); const asset = await Asset.findOne({ where: { asset_id: assetId, ...notDeleted } }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); // Browser already PUT the replacement file straight to storage via a // presigned URL (see presignAssetUpload) — this is plain JSON, no @@ -607,7 +607,7 @@ exports.updateAsset = async (req, res) => { const isDocument = asset.file_type === "document"; if (isDocument && storage_key) return R.error(res, "Document files cannot be replaced.", 400); - if (isVideo && storage_key && !req.body.is_thumbnail) return R.error(res, "Video files cannot be replaced. Upload a new asset instead.", 400); + if (isVideo && storage_key && !req.body.is_thumbnail) return R.error(res, "Video files cannot be replaced. Upload a new file instead.", 400); const storageProvider = asset.storage_provider; const usesProvider = ["chibisafe", "s3"].includes(storageProvider); @@ -641,7 +641,7 @@ exports.updateAsset = async (req, res) => { invalidateListCache(); logActivity(req.user?.user_id, 'update_asset', { entityType: 'asset', entityId: Number(assetId) }); - return R.success(res, "Asset updated.", { data: asset }); + return R.success(res, "File updated.", { data: asset }); } catch (err) { if (newUpload) await rollbackUploads([newUpload]); @@ -656,16 +656,16 @@ exports.updateAsset = async (req, res) => { exports.archiveAsset = async (req, res) => { try { const { assetId } = req.params; - if (!assetId || assetId === "undefined") return R.error(res, "Invalid asset ID.", 400); + if (!assetId || assetId === "undefined") return R.error(res, "Invalid file ID.", 400); const asset = await Asset.findOne({ where: { asset_id: assetId, ...notDeleted } }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); await asset.update({ deletedBy: req.body.deletedBy ?? null }); await asset.destroy(); invalidateListCache(); logActivity(req.user?.user_id, 'archive_asset', { entityType: 'asset', entityId: Number(assetId) }); - return R.success(res, "Asset archived."); + return R.success(res, "File archived."); } catch (err) { console.error("[ASSET][ARCHIVE]", err); return R.error(res, "Internal server error.", 500); @@ -680,7 +680,7 @@ exports.archiveAssets = async (req, res) => { if (!Array.isArray(ids) || !ids.length) return R.error(res, "ids must be a non-empty array.", 400); const assets = await Asset.findAll({ where: { asset_id: { [Op.in]: ids }, ...notDeleted } }); - if (!assets.length) return R.error(res, "No assets found.", 404); + if (!assets.length) return R.error(res, "No files found.", 404); const activeIds = assets.map((a) => a.asset_id); @@ -689,7 +689,7 @@ exports.archiveAssets = async (req, res) => { invalidateListCache(); logActivity(req.user?.user_id, 'bulk_archive_assets', { entityType: 'asset', details: { ids: activeIds, count: activeIds.length } }); - return R.success(res, `${activeIds.length} asset(s) archived.`, { + return R.success(res, `${activeIds.length} file(s) archived.`, { archived_ids: activeIds, skipped_ids: ids.filter((id) => !activeIds.includes(id)), }); @@ -706,14 +706,14 @@ exports.restoreAsset = async (req, res) => { const { assetId } = req.params; const asset = await Asset.findOne({ where: { asset_id: assetId }, paranoid: false }); - if (!asset) return R.error(res, "Asset not found.", 404); - if (!asset.deletedAt) return R.error(res, "Asset is not archived.", 400); + if (!asset) return R.error(res, "File not found.", 404); + if (!asset.deletedAt) return R.error(res, "File is not archived.", 400); await asset.restore(); await asset.update({ deletedBy: null }); invalidateListCache(); logActivity(req.user?.user_id, 'restore_asset', { entityType: 'asset', entityId: Number(assetId) }); - return R.success(res, "Asset restored.", { data: asset }); + return R.success(res, "File restored.", { data: asset }); } catch (err) { console.error("[ASSET][RESTORE]", err); return R.error(res, "Internal server error.", 500); @@ -728,10 +728,10 @@ exports.restoreAssets = async (req, res) => { if (!Array.isArray(ids) || !ids.length) return R.error(res, "ids must be a non-empty array.", 400); const assets = await Asset.findAll({ where: { asset_id: { [Op.in]: ids } }, paranoid: false }); - if (!assets.length) return R.error(res, "No assets found.", 404); + if (!assets.length) return R.error(res, "No files found.", 404); const archivedAssets = assets.filter((a) => a.deletedAt); - if (!archivedAssets.length) return R.error(res, "All selected assets are already active.", 400); + if (!archivedAssets.length) return R.error(res, "All selected files are already active.", 400); const archivedIds = archivedAssets.map((a) => a.asset_id); @@ -740,7 +740,7 @@ exports.restoreAssets = async (req, res) => { invalidateListCache(); logActivity(req.user?.user_id, 'bulk_restore_assets', { entityType: 'asset', details: { ids: archivedIds, count: archivedIds.length } }); - return R.success(res, `${archivedIds.length} asset(s) restored.`, { + return R.success(res, `${archivedIds.length} file(s) restored.`, { restored_ids: archivedIds, skipped_ids: ids.filter((id) => !archivedIds.includes(id)), }); @@ -757,8 +757,8 @@ exports.permanentlyDeleteAsset = async (req, res) => { const { assetId } = req.params; const asset = await Asset.findOne({ where: { asset_id: assetId }, paranoid: false }); - if (!asset) return R.error(res, "Asset not found.", 404); - if (!asset.deletedAt) return R.error(res, "Asset must be archived before it can be permanently deleted.", 400); + if (!asset) return R.error(res, "File not found.", 404); + if (!asset.deletedAt) return R.error(res, "File must be archived before it can be permanently deleted.", 400); const { storage_provider, storage_key, thumbnail_storage_key } = asset; @@ -778,7 +778,7 @@ exports.permanentlyDeleteAsset = async (req, res) => { invalidateListCache(); logActivity(req.user?.user_id, 'permanently_delete_asset', { entityType: 'asset', entityId: Number(assetId) }); - return R.success(res, "Asset permanently deleted."); + return R.success(res, "File permanently deleted."); } catch (err) { console.error("[ASSET][PERMANENT DELETE]", err); return R.error(res, "Internal server error.", 500); @@ -793,10 +793,10 @@ exports.permanentlyDeleteAssets = async (req, res) => { if (!Array.isArray(ids) || !ids.length) return R.error(res, "ids must be a non-empty array.", 400); const assets = await Asset.findAll({ where: { asset_id: { [Op.in]: ids } }, paranoid: false }); - if (!assets.length) return R.error(res, "No assets found.", 404); + if (!assets.length) return R.error(res, "No files found.", 404); const archivedAssets = assets.filter((a) => a.deletedAt); - if (!archivedAssets.length) return R.error(res, "All selected assets must be archived before they can be permanently deleted.", 400); + if (!archivedAssets.length) return R.error(res, "All selected files must be archived before they can be permanently deleted.", 400); const archivedIds = archivedAssets.map((a) => a.asset_id); @@ -817,7 +817,7 @@ exports.permanentlyDeleteAssets = async (req, res) => { invalidateListCache(); logActivity(req.user?.user_id, 'bulk_permanently_delete_assets', { entityType: 'asset', details: { ids: archivedIds, count: archivedIds.length } }); - return R.success(res, `${archivedIds.length} asset(s) permanently deleted.`, { + return R.success(res, `${archivedIds.length} file(s) permanently deleted.`, { deleted_ids: archivedIds, skipped_ids: ids.filter((id) => !archivedIds.includes(id)), }); @@ -840,10 +840,10 @@ exports.getArchivedAssets = async (req, res) => { findOptions: { paranoid: false, where: { deletedAt: { [Op.ne]: null } } }, }); result.data = result.data.map(redactS3Url); - return R.success(res, "Archived assets retrieved.", result); + return R.success(res, "Archived files retrieved.", result); } catch (err) { console.error("[ASSET][GET ARCHIVED]", err); - return R.error(res, "Could not retrieve archived assets.", 500); + return R.error(res, "Could not retrieve archived files.", 500); } }; diff --git a/controllers/admin/media.controller.js b/controllers/admin/media.controller.js index 26bc0ec..ccc81cc 100644 --- a/controllers/admin/media.controller.js +++ b/controllers/admin/media.controller.js @@ -30,14 +30,14 @@ exports.issueToken = async (req, res) => { attributes: ["asset_id", "file_type", "storage_provider", "storage_key", "mime_type", "thumbnail_storage_key"], }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); if (!mediaToken.SUPPORTED_TYPES.includes(asset.file_type)) { - return R.error(res, `Asset type "${asset.file_type}" is not supported.`, 400); + return R.error(res, `File type "${asset.file_type}" is not supported.`, 400); } if (asset.storage_provider !== "s3") { - return R.error(res, "Token flow is for S3 assets only. Use the raw file_url for other providers.", 400); + return R.error(res, "Token flow is for S3 files only. Use the raw file_url for other providers.", 400); } const ip = mediaToken.resolveIp(req); diff --git a/controllers/admin/notificationBroadcasts.controller.js b/controllers/admin/notificationBroadcasts.controller.js index 4794cfa..75d4778 100644 --- a/controllers/admin/notificationBroadcasts.controller.js +++ b/controllers/admin/notificationBroadcasts.controller.js @@ -73,7 +73,7 @@ async function validateImageAssetId(image_asset_id) { if (!image_asset_id) return null; const asset = await mdl_Assets.findOne({ where: { asset_id: image_asset_id, deletedAt: null } }); if (!asset) { - const err = new Error("Selected image asset was not found."); + const err = new Error("Selected image file was not found."); err.status = 400; throw err; } diff --git a/controllers/admin/tier_categories.controller.js b/controllers/admin/tier_categories.controller.js index f5bb0eb..83fdfbd 100644 --- a/controllers/admin/tier_categories.controller.js +++ b/controllers/admin/tier_categories.controller.js @@ -20,10 +20,10 @@ exports.getCategories = async (req, res) => { include: withBadge, order: [['rank', 'ASC']], }); - return R.success(res, 'Tier categories retrieved.', categories); + return R.success(res, 'Subscription categories retrieved.', categories); } catch (err) { console.error('[ADMIN][GET TIER CATEGORIES]', err); - return R.error(res, 'Could not retrieve tier categories.', 500); + return R.error(res, 'Could not retrieve subscription categories.', 500); } }; @@ -32,11 +32,11 @@ exports.getCategories = async (req, res) => { exports.getCategory = async (req, res) => { try { const cat = await mdl_TierCategories.findByPk(req.params.id, { include: withBadge }); - if (!cat) return R.error(res, 'Tier category not found.', 404); - return R.success(res, 'Tier category retrieved.', cat); + if (!cat) return R.error(res, 'Subscription category not found.', 404); + return R.success(res, 'Subscription category retrieved.', cat); } catch (err) { console.error('[ADMIN][GET TIER CATEGORY]', err); - return R.error(res, 'Could not retrieve tier category.', 500); + return R.error(res, 'Could not retrieve subscription category.', 500); } }; @@ -48,10 +48,10 @@ exports.createCategory = async (req, res) => { if (!slug || !name) return R.error(res, 'slug and name are required.', 400); const parsedRank = Number(rank ?? 1); - if (parsedRank <= 0) return R.error(res, 'Non-default tier categories must have rank greater than 0.', 400); + if (parsedRank <= 0) return R.error(res, 'Non-default subscription categories must have rank greater than 0.', 400); const exists = await mdl_TierCategories.findOne({ where: { slug } }); - if (exists) return R.error(res, `A tier category with slug "${slug}" already exists.`, 409); + if (exists) return R.error(res, `A subscription category with slug "${slug}" already exists.`, 409); const cat = await mdl_TierCategories.create({ slug, name, @@ -69,10 +69,10 @@ exports.createCategory = async (req, res) => { logActivity(req.user?.user_id, 'create_tier_category', { entityType: 'tier_category', details: { slug, name } }); const result = await mdl_TierCategories.findByPk(cat.tier_category_id, { include: withBadge }); - return R.success(res, 'Tier category created.', result, 201); + return R.success(res, 'Subscription category created.', result, 201); } catch (err) { console.error('[ADMIN][CREATE TIER CATEGORY]', err); - return R.error(res, 'Could not create tier category.', 500); + return R.error(res, 'Could not create subscription category.', 500); } }; @@ -81,13 +81,13 @@ exports.createCategory = async (req, res) => { exports.updateCategory = async (req, res) => { try { const cat = await mdl_TierCategories.findByPk(req.params.id); - if (!cat) return R.error(res, 'Tier category not found.', 404); + if (!cat) return R.error(res, 'Subscription category not found.', 404); const { name, description, rank, color, badge_asset_id, badge_icon, badge_label, is_active, is_special } = req.body; if (!cat.is_default && rank !== undefined) { const parsedRank = Number(rank); - if (parsedRank <= 0) return R.error(res, 'Non-default tier categories must have rank greater than 0.', 400); + if (parsedRank <= 0) return R.error(res, 'Non-default subscription categories must have rank greater than 0.', 400); } await cat.update({ @@ -106,10 +106,10 @@ exports.updateCategory = async (req, res) => { logActivity(req.user?.user_id, 'update_tier_category', { entityType: 'tier_category', details: { id: cat.tier_category_id, slug: cat.slug } }); const result = await mdl_TierCategories.findByPk(cat.tier_category_id, { include: withBadge }); - return R.success(res, 'Tier category updated.', result); + return R.success(res, 'Subscription category updated.', result); } catch (err) { console.error('[ADMIN][UPDATE TIER CATEGORY]', err); - return R.error(res, 'Could not update tier category.', 500); + return R.error(res, 'Could not update subscription category.', 500); } }; @@ -118,8 +118,8 @@ exports.updateCategory = async (req, res) => { exports.deleteCategory = async (req, res) => { try { const cat = await mdl_TierCategories.findByPk(req.params.id); - if (!cat) return R.error(res, 'Tier category not found.', 404); - if (cat.is_default) return R.error(res, 'The default (Free) tier category cannot be deleted.', 400); + if (!cat) return R.error(res, 'Subscription category not found.', 404); + if (cat.is_default) return R.error(res, 'The default (Free) subscription category cannot be deleted.', 400); // Block deletion if active plans still reference this category const activePlans = await mdl_TierPlans.count({ @@ -130,9 +130,9 @@ exports.deleteCategory = async (req, res) => { await cat.destroy(); logActivity(req.user?.user_id, 'delete_tier_category', { entityType: 'tier_category', details: { slug: cat.slug } }); - return R.success(res, 'Tier category deleted.'); + return R.success(res, 'Subscription category deleted.'); } catch (err) { console.error('[ADMIN][DELETE TIER CATEGORY]', err); - return R.error(res, 'Could not delete tier category.', 500); + return R.error(res, 'Could not delete subscription category.', 500); } }; diff --git a/controllers/admin/tiers.controller.js b/controllers/admin/tiers.controller.js index 67b5f2d..0351e20 100644 --- a/controllers/admin/tiers.controller.js +++ b/controllers/admin/tiers.controller.js @@ -117,10 +117,10 @@ exports.createPlan = async (req, res) => { const category = await mdl_TierCategories.findByPk(tier_category_id); if (!category || !category.is_active) - return R.error(res, 'Tier category not found or inactive.', 404); + return R.error(res, 'Subscription category not found or inactive.', 404); if (category.is_default) - return R.error(res, 'Plans cannot be created under the default (Free) tier. Free access is automatic.', 400); + return R.error(res, 'Plans cannot be created under the default (Free) subscription. Free access is automatic.', 400); const duration_days = computeDurationDays(duration_value, duration_unit); @@ -166,9 +166,9 @@ exports.updatePlan = async (req, res) => { if (updates.tier_category_id) { const category = await mdl_TierCategories.findByPk(updates.tier_category_id); if (!category || !category.is_active) - return R.error(res, 'Tier category not found or inactive.', 404); + return R.error(res, 'Subscription category not found or inactive.', 404); if (category.is_default) - return R.error(res, 'Plans cannot be moved to the Free tier category.', 400); + return R.error(res, 'Plans cannot be moved to the Free subscription category.', 400); updates.tier = category.slug; } @@ -428,10 +428,10 @@ exports.getUserTiers = async (req, res) => { ], order: [['createdAt', 'DESC']], }); - return R.success(res, 'User tiers retrieved.', tiers); + return R.success(res, 'User subscriptions retrieved.', tiers); } catch (err) { console.error('[ADMIN][GET USER TIERS]', err); - return R.error(res, 'Could not retrieve user tiers.', 500); + return R.error(res, 'Could not retrieve user subscriptions.', 500); } }; @@ -472,18 +472,18 @@ exports.grantTier = async (req, res) => { await snapshotPlanGrants(newTier, plan_id); logActivity(req.user.user_id, 'grant_tier', { entityType: 'tier', details: { user_id, tier, plan_id } }); - return R.success(res, 'Tier granted.', newTier, 201); + return R.success(res, 'Subscription granted.', newTier, 201); } catch (err) { console.error('[ADMIN][GRANT TIER]', err); - return R.error(res, 'Could not grant tier.', 500); + return R.error(res, 'Could not grant subscription.', 500); } }; exports.revokeTier = async (req, res) => { try { const tierRecord = await mdl_UserTiers.findByPk(req.params.tid); - if (!tierRecord) return R.error(res, 'Tier record not found.', 404); - if (tierRecord.status !== 'active') return R.error(res, 'Tier is not active.', 400); + if (!tierRecord) return R.error(res, 'Subscription record not found.', 404); + if (tierRecord.status !== 'active') return R.error(res, 'Subscription is not active.', 400); await tierRecord.update({ status: 'revoked', @@ -510,10 +510,10 @@ exports.revokeTier = async (req, res) => { } logActivity(req.user.user_id, 'revoke_tier', { entityType: 'tier', details: { user_id: tierRecord.user_id, tier: tierRecord.tier } }); - return R.success(res, remainingActive === 0 ? 'Tier revoked. User downgraded to free.' : 'Tier revoked.'); + return R.success(res, remainingActive === 0 ? 'Subscription revoked. User downgraded to free.' : 'Subscription revoked.'); } catch (err) { console.error('[ADMIN][REVOKE TIER]', err); - return R.error(res, 'Could not revoke tier.', 500); + return R.error(res, 'Could not revoke subscription.', 500); } }; diff --git a/controllers/client/media.controller.js b/controllers/client/media.controller.js index 8a2eb5a..28e8280 100644 --- a/controllers/client/media.controller.js +++ b/controllers/client/media.controller.js @@ -160,14 +160,14 @@ exports.issueToken = async (req, res) => { attributes: ["asset_id", "file_type", "storage_provider", "storage_key", "mime_type", "thumbnail_storage_key"], }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); if (!SUPPORTED_TYPES.includes(asset.file_type)) { - return R.error(res, `Asset type "${asset.file_type}" is not supported.`, 400); + return R.error(res, `File type "${asset.file_type}" is not supported.`, 400); } if (asset.storage_provider !== "s3") { - return R.error(res, "Token flow is for S3 assets only. Use the raw file_url for other providers.", 400); + return R.error(res, "Token flow is for S3 files only. Use the raw file_url for other providers.", 400); } // ── Bind token to the requester's IP ────────────────────────────────────── diff --git a/controllers/client/tiers.controller.js b/controllers/client/tiers.controller.js index 7984bb5..ad832de 100644 --- a/controllers/client/tiers.controller.js +++ b/controllers/client/tiers.controller.js @@ -77,7 +77,7 @@ exports.getMyTier = async (req, res) => { const freeTier = { tier: 'free', status: 'active', category: freeCategory ?? null }; // Spread freeTier at top level too — keeps `myTier.tier`/`myTier.status`/`myTier.category` // working for existing frontend code that predates the active_tiers/top_tier shape. - return R.success(res, 'Active tier retrieved.', { + return R.success(res, 'Active subscription retrieved.', { ...freeTier, active_tiers: [freeTier], top_tier: 'free', @@ -126,10 +126,10 @@ exports.getMyTier = async (req, res) => { // Spread topTierObj at top level too — keeps `myTier.tier`/`myTier.status`/ // `myTier.category`/`myTier.expires_at` working for existing frontend code // that predates the active_tiers/top_tier shape (it'll just see the best tier). - return R.success(res, 'Active tier retrieved.', { ...topTierObj, active_tiers, top_tier, just_expired, my_grants }); + return R.success(res, 'Active subscription retrieved.', { ...topTierObj, active_tiers, top_tier, just_expired, my_grants }); } catch (err) { console.error('[CLIENT][GET MY TIER]', err); - return R.error(res, 'Could not retrieve tier.', 500); + return R.error(res, 'Could not retrieve subscription.', 500); } }; @@ -139,10 +139,10 @@ exports.getMyTierHistory = async (req, res) => { where: { user_id: req.user.user_id }, order: [['createdAt', 'DESC']], }); - return R.success(res, 'Tier history retrieved.', history); + return R.success(res, 'Subscription history retrieved.', history); } catch (err) { console.error('[CLIENT][GET MY TIER HISTORY]', err); - return R.error(res, 'Could not retrieve tier history.', 500); + return R.error(res, 'Could not retrieve subscription history.', 500); } }; @@ -392,7 +392,7 @@ exports.captureOrder = async (req, res) => { expires_at: expiresAt, granted_by: null, }); - successMessage = 'Payment successful. Tier activated.'; + successMessage = 'Payment successful. Subscription activated.'; } // Snapshot the plan's current bundle contents into user_tier_grants — @@ -471,7 +471,7 @@ exports.refundOrder = async (req, res) => { where: activeTierWhere, order: [['createdAt', 'DESC']], }); - if (!activeTierCandidates.length) return R.error(res, 'No active tier to refund.', 404); + if (!activeTierCandidates.length) return R.error(res, 'No active subscription to refund.', 404); if (activeTierCandidates.length > 1) { return R.error(res, 'You have more than one active subscription — specify plan_id to refund a specific one.', 400); } @@ -481,7 +481,7 @@ exports.refundOrder = async (req, res) => { where: { user_id, tier_id: activeTier.tier_id, status: 'completed' }, order: [['paid_at', 'DESC']], }); - if (!payment) return R.error(res, 'No completed payment found for this tier.', 404); + if (!payment) return R.error(res, 'No completed payment found for this subscription.', 404); // Load plan's payment policy to get the configured refund window const policy = await paymentSvc.getPolicyForPlan(payment.plan_id); @@ -608,10 +608,10 @@ exports.getCategories = async (req, res) => { include: [{ model: Asset, as: 'badgeAsset', attributes: ['asset_id', 'storage_provider', 'file_url', 'display_name'], required: false }], order: [['rank', 'ASC']], }); - return R.success(res, 'Tier categories retrieved.', categories); + return R.success(res, 'Subscription categories retrieved.', categories); } catch (err) { console.error('[CLIENT][GET TIER CATEGORIES]', err); - return R.error(res, 'Could not retrieve tier categories.', 500); + return R.error(res, 'Could not retrieve subscription categories.', 500); } }; diff --git a/controllers/public/media.controller.js b/controllers/public/media.controller.js index fdaacf4..206443b 100644 --- a/controllers/public/media.controller.js +++ b/controllers/public/media.controller.js @@ -44,17 +44,17 @@ exports.issueToken = async (req, res) => { attributes: ["asset_id", "file_type", "storage_provider", "storage_key", "mime_type", "is_public"], }); - if (!asset) return R.error(res, "Asset not found.", 404); + if (!asset) return R.error(res, "File not found.", 404); // Private assets are never served through the public endpoint if (!asset.is_public) return R.error(res, "Forbidden.", 403); if (!SUPPORTED_TYPES.includes(asset.file_type)) { - return R.error(res, `Asset type "${asset.file_type}" is not supported.`, 400); + return R.error(res, `File type "${asset.file_type}" is not supported.`, 400); } if (asset.storage_provider !== "s3") { - return R.error(res, "Token flow is for S3 assets only. Use the raw file_url for other providers.", 400); + return R.error(res, "Token flow is for S3 files only. Use the raw file_url for other providers.", 400); } const ip = resolveIp(req); diff --git a/data/email_body.data.js b/data/email_body.data.js index 6bd267e..1c411fc 100644 --- a/data/email_body.data.js +++ b/data/email_body.data.js @@ -172,7 +172,7 @@ const emailTemplates = { StatusAccess Revoked RefundNot applicable — this subscription is non-refundable -

Your account no longer has access to the courses, units, and lessons included in this plan. If you were not concurrently subscribed to another active plan, your account has reverted to the Free tier.

+

Your account no longer has access to the courses, units, and lessons included in this plan. If you were not concurrently subscribed to another active plan, your account has reverted to the Free subscription.

If you believe this was done in error or have questions about this change, please contact our support team.

`), }), @@ -188,7 +188,7 @@ const emailTemplates = { Refund ID${refundId} StatusRefunded -

Your access to the courses, units, and lessons included in this plan has been revoked effective immediately. If you were not concurrently subscribed to another active plan, your account has reverted to the Free tier.

+

Your access to the courses, units, and lessons included in this plan has been revoked effective immediately. If you were not concurrently subscribed to another active plan, your account has reverted to the Free subscription.

Please allow a few business days for the refunded amount to reflect on your original payment method, depending on your provider.

If you have any questions about this refund, please contact our support team.

`), diff --git a/models/advertisements/advertisements.placements.js b/models/advertisements/advertisements.placements.js index f55d18b..b53dd06 100644 --- a/models/advertisements/advertisements.placements.js +++ b/models/advertisements/advertisements.placements.js @@ -14,7 +14,7 @@ const PLACEMENTS = [ { key: "dashboard.hero", format: "hero", page: "dashboard", pageLabel: "Dashboard", slotLabel: "Hero (top of page)" }, - { key: "tier_plans.banner", format: "banner", page: "tier_plans", pageLabel: "Tier Plans", slotLabel: "Banner (above plan cards)" }, + { key: "tier_plans.banner", format: "banner", page: "tier_plans", pageLabel: "Subscriptions", slotLabel: "Banner (above plan cards)" }, { key: "course_details.banner", format: "banner", page: "course_details", pageLabel: "Course Details", slotLabel: "Banner (below hero)" }, ];