Thank you for considering contributing to CS2Inspect! This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Getting Started
- Development Workflow
- Code Standards
- Pull Request Process
- Issue Guidelines
- Documentation
- Testing
- Be respectful and inclusive
- Welcome newcomers and help them learn
- Accept constructive criticism gracefully
- Focus on what is best for the community
- Show empathy towards other contributors
- Harassment, discrimination, or personal attacks
- Trolling, insulting comments, or political attacks
- Publishing private information without permission
- Unprofessional conduct
Before contributing, ensure you have:
- Development Environment: Node.js 16+, MariaDB, Git
- GitHub Account: For submitting pull requests
- Local Setup: Follow the Setup Guide
If you're new to the project:
-
Read the Documentation:
-
Look for Good First Issues:
- Check GitHub Issues with label
good first issue - These are beginner-friendly tasks
- Check GitHub Issues with label
-
Join the Community:
- Comment on issues you're interested in
- Ask questions if you're unsure
- Introduce yourself in discussions
# Fork the repository on GitHub
# Then clone your fork
git clone https://github.com/YOUR_USERNAME/cs2inspect-web.git
cd cs2inspect-web
# Add upstream remote
git remote add upstream https://github.com/sak0a/cs2inspect-web.gitUse descriptive branch names following this pattern:
# Feature branches
git checkout -b feature/add-weapon-preview
# Bug fix branches
git checkout -b fix/sticker-positioning-bug
# Documentation branches
git checkout -b docs/update-api-reference
# Refactoring branches
git checkout -b refactor/optimize-loadout-storeBranch Naming Conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions or modificationschore/- Build process or dependency updates
Follow the code standards (see below) and make your changes:
# Make changes to files
# ...
# Run tests
npm test
# Run linter
npm run lint
# Fix linting issues
npm run lint -- --fixWrite clear, descriptive commit messages:
git add .
git commit -m "Add weapon preview feature
- Implement 3D weapon preview component
- Add rotation controls
- Support for all weapon types
- Include unit tests"Commit Message Format:
<type>: <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringtest: Test additions or changeschore: Build process or dependency updates
Example:
feat: Add sticker wear slider
Implement a slider component for adjusting sticker wear value.
Supports values from 0.0 (pristine) to 1.0 (fully scratched).
Closes #123
git push origin feature/add-weapon-preview- Go to your fork on GitHub
- Click "Compare & pull request"
- Fill out the PR template (see below)
- Submit the pull request
// âś… GOOD: Use TypeScript interfaces for types
interface WeaponConfig {
defindex: number
paintindex: number
paintwear: number
}
// ❌ AVOID: Using 'any' type
function processWeapon(weapon: any) { }
// âś… GOOD: Properly typed
function processWeapon(weapon: WeaponConfig) { }
// âś… GOOD: Use const for immutable values
const MAX_FLOAT = 1.0
// âś… GOOD: Use descriptive variable names
const weaponDefindex = 7
// ❌ AVOID: Single letter or unclear names
const w = 7// 1. Vue/Nuxt imports
import { ref, computed } from 'vue'
import { defineEventHandler } from 'h3'
// 2. External libraries
import { useMessage } from 'naive-ui'
// 3. Internal types
import type { WeaponConfiguration } from '~/types'
// 4. Components
import WeaponSkinModal from '~/components/WeaponSkinModal.vue'
// 5. Utils and composables
import { useInspectItem } from '~/composables/useInspectItem'// âś… GOOD: Import types from main index
import type { WeaponConfiguration, APIWeaponSkin } from '~/types'
// ❌ AVOID: Direct module imports
import type { WeaponConfiguration } from '~/types/business/items'<script setup lang="ts">
// 1. Imports
import { ref, computed } from 'vue'
import type { PropType } from 'vue'
// 2. Props interface
interface Props {
weapon: WeaponData
show?: boolean
}
// 3. Props definition
const props = withDefaults(defineProps<Props>(), {
show: false
})
// 4. Emits
const emit = defineEmits<{
(e: 'save', weapon: WeaponData): void
(e: 'close'): void
}>()
// 5. State
const selectedSkin = ref<number | null>(null)
// 6. Computed
const isValid = computed(() => selectedSkin.value !== null)
// 7. Methods
const handleSave = () => {
if (!isValid.value) return
emit('save', { ...props.weapon, paintindex: selectedSkin.value })
}
// 8. Lifecycle hooks
onMounted(() => {
// Initialize
})
</script>
<template>
<div class="weapon-modal">
<!-- Template content -->
</div>
</template>
<style scoped>
/* Component-specific styles */
.weapon-modal {
/* ... */
}
</style><template>
<!-- âś… GOOD: Use semantic HTML -->
<section class="weapon-list">
<header>
<h2>Weapons</h2>
</header>
<article v-for="weapon in weapons" :key="weapon.id">
<!-- Weapon card -->
</article>
</section>
<!-- âś… GOOD: Use v-show for frequent toggles -->
<div v-show="isVisible">Content</div>
<!-- âś… GOOD: Use v-if for conditional rendering -->
<div v-if="hasData">Data content</div>
<div v-else>No data</div>
<!-- âś… GOOD: Proper event binding -->
<button @click="handleClick">Click me</button>
<!-- ❌ AVOID: Inline complex logic -->
<button @click="condition ? doThis() : doThat()">Bad</button>
<!-- âś… GOOD: Extract to method -->
<button @click="handleAction">Good</button>
</template><template>
<!-- âś… GOOD: Logical grouping of classes -->
<div class="flex items-center justify-between p-4 bg-gray-800 rounded-lg">
<!-- âś… GOOD: Use custom CSS variables -->
<div class="ring-2 ring-[var(--selection-ring)]">
<!-- âś… GOOD: Responsive design -->
<div class="w-full md:w-1/2 lg:w-1/3">
<!-- ❌ AVOID: Excessive inline classes -->
<div class="w-full h-full flex items-center justify-center p-4 m-2 bg-gray-800 text-white font-bold text-xl rounded-lg shadow-md hover:shadow-lg transition-all duration-300">
</template>// âś… GOOD: Use SASS features
.weapon-card {
@apply bg-gray-800 rounded-lg p-4;
&:hover {
@apply shadow-lg;
}
.weapon-name {
@apply text-xl font-bold;
}
}
// âś… GOOD: Use CSS variables
.theme-accent {
color: var(--selection-ring);
border-color: var(--selection-ring);
}// server/api/weapons/save.ts
import { defineEventHandler, readBody } from 'h3'
import type { WeaponSaveRequest } from '~/types'
export default defineEventHandler(async (event) => {
try {
// 1. Validate authentication
const user = await requireAuth(event)
// 2. Parse and validate request body
const body = await readBody<WeaponSaveRequest>(event)
if (!body.weaponDefindex) {
throw createError({
statusCode: 400,
message: 'Invalid weapon data'
})
}
// 3. Perform business logic
const result = await saveWeaponToDatabase(user.steamId, body)
// 4. Return standardized response
return {
success: true,
data: result
}
} catch (error: any) {
// 5. Handle errors consistently
console.error('Error saving weapon:', error)
throw createError({
statusCode: error.statusCode || 500,
message: error.message || 'Failed to save weapon'
})
}
})Before submitting a pull request, ensure:
- Code follows the project's style guide
- All tests pass (
npm test) - Linter passes (
npm run lint) - New tests added for new features
- Documentation updated if needed
- Commit messages are clear and descriptive
- Branch is up to date with
main - No merge conflicts
- Screenshots included for UI changes
## Description
Brief description of changes made.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
- [ ] Code refactoring
## Related Issue
Closes #123
## Changes Made
- Change 1
- Change 2
- Change 3
## Testing
Describe how you tested your changes:
- Unit tests added/updated
- Manual testing performed
- Edge cases considered
## Screenshots (if applicable)
Add screenshots for UI changes.
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] No new warnings
- [ ] Tests added/updated
- [ ] All tests pass- Automated Checks: CI/CD runs tests and linting
- Code Review: Maintainers review code
- Feedback: Address review comments
- Approval: At least one maintainer approval required
- Merge: Maintainer merges the PR
**Describe the bug**
A clear description of what the bug is.
**To Reproduce**
Steps to reproduce:
1. Go to '...'
2. Click on '...'
3. See error
**Expected behavior**
What you expected to happen.
**Screenshots**
If applicable, add screenshots.
**Environment:**
- Browser: [e.g. Chrome 120]
- OS: [e.g. Windows 11]
- Version: [e.g. 1.0.0]
**Additional context**
Any other relevant information.**Is your feature request related to a problem?**
Description of the problem.
**Describe the solution you'd like**
Clear description of desired functionality.
**Describe alternatives you've considered**
Alternative solutions or features.
**Additional context**
Any other relevant information, mockups, or examples.bug- Something isn't workingenhancement- New feature or requestdocumentation- Documentation improvementsgood first issue- Good for newcomershelp wanted- Extra attention neededquestion- Further information requestedwontfix- This will not be worked on
Update documentation when:
- Adding new features
- Changing existing functionality
- Fixing significant bugs
- Improving setup or deployment process
- Adding new API endpoints
# Clear Title
## Section Headers
Use descriptive headers that explain the content.
### Code Examples
Provide clear, working code examples:
\`\`\`typescript
// Example code with comments
const example = doSomething()
\`\`\`
### Lists
- Use bullet points for unordered lists
- Keep items concise
- Be consistent with punctuation
1. Use numbered lists for sequential steps
2. Ensure steps are clear and complete
3. Test that steps actually work
### Links
Link to related documentation:
- [Related Doc](related.md)
- [External Resource](https://example.com)// components/WeaponTabs.spec.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import WeaponTabs from './WeaponTabs.vue'
describe('WeaponTabs', () => {
it('renders weapon categories', () => {
const wrapper = mount(WeaponTabs)
expect(wrapper.find('.weapon-category').exists()).toBe(true)
})
it('emits selection event when weapon clicked', async () => {
const wrapper = mount(WeaponTabs)
await wrapper.find('.weapon-item').trigger('click')
expect(wrapper.emitted('select')).toBeTruthy()
})
})// server/api/weapons/save.spec.ts
import { describe, it, expect } from 'vitest'
import { createEvent } from '@nuxt/test-utils'
describe('POST /api/weapons/save', () => {
it('saves weapon successfully', async () => {
const event = createEvent({
method: 'POST',
body: {
weaponDefindex: 7,
paintindex: 253
}
})
const response = await handler(event)
expect(response.success).toBe(true)
})
})# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Run specific test file
npm test components/WeaponTabs.spec.ts- Documentation: Check the docs/ directory
- Issues: Search existing GitHub Issues
- Discussions: Use GitHub Discussions for questions
- Email: Contact maintainers (if provided)
By contributing to CS2Inspect, you agree that your contributions will be licensed under the project's license.
Thank you for contributing to CS2Inspect! Your time and effort help make this project better for everyone.
- Setup Guide - Development environment setup
- Architecture - System architecture
- Components - Component documentation
- API Reference - API documentation