Skip to content

Feature/issues 634 635 648 649#751

Merged
Hexstar-labs merged 5 commits into
BrainTease:mainfrom
Pilot39:feature/issues-634-635-648-649
Jun 29, 2026
Merged

Feature/issues 634 635 648 649#751
Hexstar-labs merged 5 commits into
BrainTease:mainfrom
Pilot39:feature/issues-634-635-648-649

Conversation

@Pilot39

@Pilot39 Pilot39 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Closes #634


Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Dependency update
  • CI/CD improvement

Related Issues

Closes #

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • E2E tests added/updated (if applicable)
  • Manual testing performed

Documentation

  • README updated (if applicable)
  • API documentation updated (if applicable)
  • Code comments added for complex logic
  • Migration guide added (if breaking changes)

Breaking Changes

  • No breaking changes
  • Breaking changes documented below:

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests passed locally with my changes
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Context

Closes #635
Closes #648
Closes #649

Pilot39 and others added 5 commits June 29, 2026 09:31
…ards

- Rewrite contracts/token/src/staking.rs with full delegation support
- DelegationRecord: delegator, delegatee, amount, epoch, rewards_accrued, reward_debt
- Global reward-per-token accumulator (scaled 1e12) updated each epoch
- delegate(): create delegation, add to total staked, snapshot reward debt
- undelegate(): compute pending rewards, remove delegation, emit event
- claim_rewards(): settle pending rewards for direct stakers without withdrawing
- withdraw(): net = principal + rewards - optional early penalty (checked arithmetic)
- set_slash_config() / slash(): admin-gated slashing with configurable rate and recipient
- accrue_global(): epoch-based accumulator update (rounding-safe, division-last)
- pending_rewards(): correct proportional accrual across arbitrary epochs
- Events: stake, unstake, reward, delegate, undelegate, slashed
- New keys: Delegation, DelegatorTargets, RewardPerToken, StakerRewardDebt, SlashConfig, SlashEnabled
- 8 unit tests: stake/withdraw, early penalty, delegate/undelegate, rewards across epochs,
  slash, self-delegation guard, overflow safety

Closes BrainTease#634
- Create contracts/credential_metadata/src/linkage.rs
  - CredentialNftLink: credential_id, nft_id, nft_contract, linked_at
  - LinkageKey enum: CredentialNft, NftCredential, NftContract
  - issue_and_mint_nft(): cross-contract call to NFT mint_course_nft, atomic rollback on failure
  - unlink(): remove both directions of the link
  - Getters: get_credential_nft_link, get_nft_credential (reverse lookup), is_linked
  - nft_contract_client stub (contractclient trait for cross-contract call)
  - 4 unit tests covering not-linked state and unlink panic
- Update contracts/credential_metadata/src/lib.rs
  - Expose linkage module with pub use
  - initialize_with_nft(): init + set NFT contract in one call
  - issue_with_nft(): store metadata + atomically call NFT contract; failure rolls back both
  - get_credential_link(), get_nft_credential_id(), credential_is_linked() getters

Closes BrainTease#635
- Create apps/backend/src/jobs/job.entity.ts
  - Job entity: title, description, category, requiredSkills (array), budgetMin/Max,
    status (open/closed/expired/filled), expiresAt, isDeleted, instructor relation
  - JobApplication entity: jobId, applicantId, coverLetter, status, reviewNote
  - Indexes: (status, expiresAt), (jobId, applicantId unique), (applicantId, status)
- Create apps/backend/src/jobs/dto/index.ts
  - CreateJobDto, UpdateJobDto, CreateApplicationDto, UpdateApplicationStatusDto, JobQueryDto
- Create apps/backend/src/jobs/jobs.service.ts
  - createJob(): create with ownerId, emit job.created event
  - findAll(): paginated with search (ILike), category, status filters
  - update() / remove(): ownership-gated
  - apply(): validates open status, prevents self-apply, rejects duplicates
  - getApplicationsForJob(): poster-only
  - getMyApplications(): applicant's own applications
  - updateApplicationStatus(): poster-only, emits status_changed, marks job FILLED on accept
  - withdraw(): applicant can withdraw pending/reviewed applications
  - getMatchingJobs(): skill intersection scoring, sorted by score desc
  - expireOldJobs(): @Cron(EVERY_HOUR) — marks expired jobs, emits job.expired event
- Create apps/backend/src/jobs/jobs.controller.ts
  - GET /jobs, POST /jobs, PATCH /jobs/:id, DELETE /jobs/:id
  - GET /jobs/recommendations (auth required)
  - POST /jobs/:id/apply, GET /jobs/:id/applications
  - GET /jobs/applications/mine, PATCH /jobs/applications/:id/status
  - PATCH /jobs/applications/:id/withdraw
- Create apps/backend/src/jobs/jobs.module.ts

Closes BrainTease#648
- Create apps/backend/src/media/media.entity.ts
  - Media entity: ownerId, originalName, mimeType, sizeBytes, storageKey,
    bucket, publicUrl, status (pending/ready/failed/deleted), derivatives (jsonb),
    metadata (jsonb), uploadedAt, deletedAt
  - Indexes on ownerId and status
- Create apps/backend/src/media/storage.service.ts
  - validateFile(): checks MIME type against allowlist, extension allowlist, max 50MB
  - sanitiseFilename(): strips path separators, non-ASCII chars, limits to 80 chars + ext
  - upload(): validate, sanitise, upload original to S3 (AES256 SSE), generate responsive
    WebP derivatives (thumb 150, small 400, medium 800) via Sharp, persist Media record
  - getSignedUrl(): pre-signed S3 GET URL with configurable TTL (default 1h)
  - getDerivativeSignedUrl(): signed URL for a specific derivative suffix
  - softDelete(): mark status=deleted, set deletedAt (S3 object retained)
  - hardDelete(): delete original and all derivatives from S3, remove DB record
  - findByOwner() / findById(): metadata queries
  - AWS SDK v3 (PutObjectCommand, GetObjectCommand, DeleteObjectCommand)
  - S3 endpoint configurable for MinIO/localstack local dev
- Create apps/backend/src/media/media.controller.ts
  - POST /media/upload (multer memoryStorage, 50MB limit)
  - GET /media/mine
  - GET /media/:id/url?ttl=
  - GET /media/:id/url/:suffix (derivatives)
  - DELETE /media/:id (soft), DELETE /media/:id/purge (hard)
  - All routes require JwtAuthGuard
- Create apps/backend/src/media/media.module.ts

Closes BrainTease#649
@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@Pilot39 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Hexstar-labs Hexstar-labs merged commit b644c69 into BrainTease:main Jun 29, 2026
9 of 44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants