We are going to create the start of a database on mechanical keyboard switches. I am wanting to get as much information as possible, but accuracy is more important than quantity. If you do not have information about a specific characteristic, leaving it empty is a perfect response. The site is just a fun resource for keyboard/switch enthousiest. The data will be used to help visitors find switches they might like. They will also be able to make list of switches that they own and want to get still.
No need to provide an ID, CreatedAt or UpdatedAt they will be generated by the DB. For timestamps, please use the 2024-08-05 12:42:33.170598+00 format
The expected output will be, to ensure the data is accurate and to include the needed information to populate the details. It is okay if the details are not know, just trying to get as much information as possible. Accuracy is more important that quantity. No need to provide images. Each switch should have a single details. In the rare case that a same named switch has more than one type, it would get 2 differnt details
- Data Sources: Are there specific sources or websites you'd like me to use for gathering the switch information? Some popular ones include Reddit's Mechanical Keyboard subreddit, GeekHack forums, and vendors like NovelKeys and MechanicalKeyboards.com.
- Accuracy: Since accuracy is important, should we prioritize official specifications from the manufacturer's website over user-generated content like reviews or forum posts?
- Switch Characteristics: Are there any specific characteristics you want to ensure are included for each switch beyond what you’ve listed, such as actuation force, travel distance, or specific materials used in the stem or housing?
- Price Point Definition: How do you define the "PricePoint" for the switches? For example, is there a specific price range for each category (1 - value, 2 - average, 3 - expensive)?
- Unique Attributes: Are there any unique attributes or features you're interested in capturing, such as RGB support, hot-swap compatibility, or specific market trends?
- Switches to Start With: Do you have a list of switches or brands you'd like to start with? We could begin with popular ones like Cherry MX, Gateron, and Kailh switches.
- Database Structure: You've provided a comprehensive Go struct for the Switch type, but do you have a specific structure in mind for how you'd like to store additional attributes or detailed specifications?
- Images: Would you like to include images of the switches or a link to an image gallery as part of the data?
Any source is fine. 2. Yes, I would prioritize what the manufacture says first, but other resources are fine. 3. No, we will do this later. Right now just getting the basics. 4. I don't have a good reference, this can be generalized/estimates its the one value that accuracy is ok, best. Best guess is fine. 5. Not at this time, just getting general information. 6. Yes, I will provide that. We wont get everything at once. 7. Yes, there will be a separate table handling the characteristics of the switch, right not just getting the list of switches and basic information. 8. Do not provide images at this time
Below I have included the base to use for building the switch data, which please provide as a Go slice. A summary or providing a full file is not needed, can just provide the go slice. Here is an example output thats expected.
{
Name: "MX2A Silent Red",
ShortDescription: "Silent linear switch with RGB support and a smooth feel.",
LongDescription: "The Cherry MX2A Silent Red Linear switch features a quiet and smooth keystroke, making it perfect for quiet environments such as offices or shared spaces. With an actuation force of 45 grams, this switch ensures a light touch while minimizing noise through built-in dampeners. The RGB lighting adds a customizable visual element, making it an excellent choice for those who want both a serene typing experience and a vibrant keyboard.",
ManufacturerID: ptr(1), // Cherry
BrandID: ptr(1), // Cherry
SwitchTypeID: 4, // Silent Linear
ReleaseDate: parseDate("2024-03-01"),
Available: true,
PricePoint: 3, // Expensive
SiteURL: "https://www.cherry-world.com/mx2a-silent-red",
ImageLinks: []models.ImageLink{
{
LinkAddress: "https://www.cherry-world.com/media/catalog/product/cache/661c0bae3bb54b88fbb1b415a9d390cb/m/x/mx3a-l1na_l1nn_image.jpg",
AltText: "Cherry MX2A Silent Red switch",
OwnerType: "switches",
},
},
Details: models.Details{
SpringForce: ptr(float32(45)),
ActuationPoint: ptr(float32(2.0)),
ActuationForce: ptr(float32(45)),
BottomOutForce: ptr(float32(60)),
BottomOutForcePoint: ptr(float32(4.0)),
TotalTravel: ptr(float32(4.0)),
PreTravel: ptr(float32(2.0)),
FactoryLubed: true,
StemMaterialID: ptr(23), // POM
TopHousingMaterialID: ptr(26), // Polycarbonate
BaseHousingMaterialID: ptr(24), // Nylon
SpringMaterialTypeID: ptr(17), // Steel
StemColorID: ptr(45), // Red
TopHousingColorID: ptr(49), // Clear
BottomHousingColorID: ptr(49), // Clear
PinConfigurationID: ptr(74), // 3-Pin
SoundTypeID: ptr(35), // Quiet
SoundLevelID: ptr(28), // Very Low
HasShineThrough: ptr(true),
},
},
Here are the helper functions for reference, they do not need to be included in results:
func ptr(i int) *int {
return &i
}
func parseDate(date string) *time.Time {
t, _ := time.Parse("2006-01-02", date)
return &t
}
Here is the switch struct that we are working with
type Switch struct {
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v7();primaryKey" json:"id"`
Name string `gorm:"type:varchar(50);not null;index:idx_name;uniqueIndex:idx_name_manufacturer_type" json:"name"`
ShortDescription string `gorm:"type:varchar(255);not null" json:"shortDescription"`
LongDescription string `gorm:"type:text;not null" json:"longDescription"`
ManufacturerID *int `gorm:"type:int;index;uniqueIndex:idx_name_manufacturer_type" json:"manufacturerId,omitempty"`
Manufacturer *Producer `gorm:"foreignKey:ManufacturerID" json:"manufacturer,omitempty"`
BrandID *int `gorm:"type:int;index" json:"brandId,omitempty"`
Brand *Producer `gorm:"foreignKey:BrandID" json:"brand,omitempty"`
SwitchTypeID int `gorm:"type:int;not null;index;uniqueIndex:idx_name_manufacturer_type" json:"switchTypeId"`
SwitchType *Type `gorm:"foreignKey:SwitchTypeID" json:"switchType,omitempty"`
ReleaseDate *time.Time `gorm:"type:date" json:"releaseDate,omitempty"`
Available bool `gorm:"type:boolean;default:true" json:"available"`
PricePoint int `gorm:"type:int;not null" json:"pricePoint"`
SiteURL string `gorm:"type:varchar(255)" json:"siteURL,omitempty"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"`
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"deletedAt"`
CreatedByID uuid.UUID `gorm:"type:uuid" json:"createdById"`
CreatedBy User `gorm:"foreignKey:CreatedByID;references:ID" json:"createdBy,omitempty"`
UpdatedByID uuid.UUID `gorm:"type:uuid" json:"updatedById"`
UpdatedBy User `gorm:"foreignKey:UpdatedByID;references:ID" json:"updatedBy,omitempty"`
ImageLinks []ImageLink `gorm:"polymorphic:Owner;polymorphicValue:switch;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"imageLinks,omitempty"`
Ratings []Rating `gorm:"foreignKey:SwitchID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"ratings,omitempty"`
AverageRating float64 `gorm:"type:float;default:0.0" json:"averageRating,omitempty"`
RatingsCount int `gorm:"type:int;default:0" json:"ratingsCount,omitempty"`
UserRating *Rating `gorm:"-" json:"userRating,omitempty"`
Details Details `gorm:"foreignKey:SwitchID;references:ID" json:"details,omitempty"`
}
type Details struct {
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v7();primaryKey" json:"id"`
SwitchID uuid.UUID `gorm:"type:uuid;not null;index" json:"switchId"`
Version *int `gorm:"type:int" json:"version,omitempty"`
SpringTypeID *int `gorm:"type:int" json:"springTypeId,omitempty"`
SpringForce *float32 `gorm:"type:real" json:"springForce,omitempty"`
SpringMaterialTypeID *int `gorm:"type:int" json:"springMaterialTypeId,omitempty"`
SpringMaterialType *Type `gorm:"foreignKey:SpringMaterialTypeID" json:"springMaterialType,omitempty"`
TopHousingMaterialID *int `gorm:"type:int" json:"topHousingMaterialId,omitempty"`
TopHousingMaterial *Type `gorm:"foreignKey:TopHousingMaterialID" json:"topHousingMaterial,omitempty"`
BaseHousingMaterialID *int `gorm:"type:int" json:"baseHousingMaterialId,omitempty"`
BaseHousingMaterial *Type `gorm:"foreignKey:BaseHousingMaterialID" json:"baseHousingMaterial,omitempty"`
StemMaterialID *int `gorm:"type:int" json:"stemMaterialId,omitempty"`
StemMaterial *Type `gorm:"foreignKey:StemMaterialID" json:"stemMaterial,omitempty"`
HasShineThrough *bool `gorm:"type:boolean" json:"hasShineThrough,omitempty"`
PreTravel *float32 `gorm:"type:real" json:"preTravel,omitempty"`
TotalTravel *float32 `gorm:"type:real" json:"totalTravel,omitempty"`
InitialForce *float32 `gorm:"type:real" json:"initialForce,omitempty"`
ActuationPoint *float32 `gorm:"type:real" json:"actuationPoint,omitempty"`
ActuationForce *float32 `gorm:"type:real" json:"actuationForce,omitempty"`
ResetPoint *float32 `gorm:"type:real" json:"resetPoint,omitempty"`
BottomOutForcePoint *float32 `gorm:"type:real" json:"bottomOutForcePoint,omitempty"`
BottomOutForce *float32 `gorm:"type:real" json:"bottomOutForce,omitempty"`
SoundLevelID *int `gorm:"type:int" json:"soundLevelId,omitempty"`
SoundLevel *Type `gorm:"foreignKey:SoundLevelID" json:"soundLevel,omitempty"`
SoundTypeID *int `gorm:"type:int" json:"soundTypeId,omitempty"`
SoundType *Type `gorm:"foreignKey:SoundTypeID" json:"soundType,omitempty"`
TactilityTypeID *int `gorm:"type:int" json:"tactilityTypeId,omitempty"`
TactilityType *Type `gorm:"foreignKey:TactilityTypeID" json:"tactilityType,omitempty"`
BumpPosition *float32 `gorm:"type:real" json:"bumpPosition,omitempty"`
BumpForce *float32 `gorm:"type:real" json:"bumpForce,omitempty"`
TactilityFeedbackID *int `gorm:"type:int" json:"tactilityFeedbackId,omitempty"`
TactilityFeedback *Type `gorm:"foreignKey:TactilityFeedbackID" json:"tactilityFeedback,omitempty"`
FactoryLubed bool `gorm:"type:boolean;default:false" json:"factoryLubed"`
StemColorID *int `gorm:"type:int" json:"stemColorId,omitempty"`
StemColor *Type `gorm:"foreignKey:StemColorID" json:"stemColor,omitempty"`
TopHousingColorID *int `gorm:"type:int" json:"topHousingColorId,omitempty"`
TopHousingColor *Type `gorm:"foreignKey:TopHousingColorID" json:"topHousingColor,omitempty"`
BottomHousingColorID *int `gorm:"type:int" json:"bottomHousingColorId,omitempty"`
BottomHousingColor *Type `gorm:"foreignKey:BottomHousingColorID" json:"bottomHousingColor,omitempty"`
PinConfigurationID *int `gorm:"type:int" json:"pinConfigurationId,omitempty"`
PinConfiguration *Type `gorm:"foreignKey:PinConfigurationID" json:"pinConfiguration,omitempty"`
CreatedAt time.Time `gorm:"type:timestamp;autoCreateTime" json:"createdAt"`
UpdatedAt time.Time `gorm:"type:timestamp;autoUpdateTime" json:"updatedAt"`
}
Name - Common name of the switch ShortDescription - This is a simple and small description of the switch, please keep this to less than 255 characters LongDescription - This is a more detailed description of the switch and can be as long as needed to describe the data. ManufacturerID - References the id from the producers table and is for who actually manufacturers the switch BrandID - References the id from the producers table and indicates the brand the switch is sold under. This can be the same as the manufacturer SwitchTypeID - This references the id from the types data, specificially the ones from the switch_type category ReleaseDate - When was the switch made available. Note: Rough estimates are ok for this field and not critical Available - Is the switch currently available PricePoint - This is an int from 1 - 3. 1 is a value switch, 2 is average costing switch and 3 is an expensive switch
Types Data
[
{ "id": "1", "name": "Linear", "code": "linear", "category": "switch_type" },
{
"id": "2",
"name": "Tactile",
"code": "tactile",
"category": "switch_type"
},
{ "id": "3", "name": "Clicky", "code": "clicky", "category": "switch_type" },
{
"id": "4",
"name": "Silent Linear",
"code": "silent_linear",
"category": "switch_type"
},
{
"id": "5",
"name": "Silent Tactile",
"code": "silent_tactile",
"category": "switch_type"
},
{
"id": "6",
"name": "Linear",
"code": "spring_linear",
"category": "spring_type"
},
{
"id": "7",
"name": "Progressive",
"code": "progressive",
"category": "spring_type"
},
{ "id": "8", "name": "Slow", "code": "slow", "category": "spring_type" },
{ "id": "9", "name": "Fast", "code": "fast", "category": "spring_type" },
{
"id": "10",
"name": "Variable",
"code": "variable",
"category": "spring_type"
},
{
"id": "11",
"name": "Balanced",
"code": "balanced",
"category": "spring_type"
},
{ "id": "12", "name": "Soft", "code": "soft", "category": "spring_type" },
{ "id": "13", "name": "Heavy", "code": "heavy", "category": "spring_type" },
{ "id": "14", "name": "Custom", "code": "custom", "category": "spring_type" },
{
"id": "15",
"name": "Dual-Stage",
"code": "dual_stage",
"category": "spring_type"
},
{
"id": "16",
"name": "Triple-Stage",
"code": "triple_stage",
"category": "spring_type"
},
{
"id": "17",
"name": "Steel",
"code": "steel",
"category": "spring_material"
},
{
"id": "18",
"name": "Gold-Plated Steel",
"code": "gold_plated_steel",
"category": "spring_material"
},
{
"id": "19",
"name": "Copper",
"code": "copper",
"category": "spring_material"
},
{
"id": "20",
"name": "Phosphor Bronze",
"code": "phosphor_bronze",
"category": "spring_material"
},
{
"id": "21",
"name": "Stainless Steel",
"code": "stainless_steel",
"category": "spring_material"
},
{ "id": "22", "name": "ABS", "code": "abs", "category": "material" },
{ "id": "23", "name": "POM", "code": "pom", "category": "material" },
{ "id": "24", "name": "Nylon", "code": "nylon", "category": "material" },
{ "id": "25", "name": "UHMWPE", "code": "uhmwpe", "category": "material" },
{ "id": "26", "name": "Polycarbonate", "code": "pc", "category": "material" },
{ "id": "27", "name": "PBT", "code": "pbt", "category": "material" },
{
"id": "28",
"name": "Very Low",
"code": "very_low",
"category": "sound_level"
},
{ "id": "29", "name": "Low", "code": "low", "category": "sound_level" },
{ "id": "30", "name": "Medium", "code": "medium", "category": "sound_level" },
{ "id": "31", "name": "High", "code": "high", "category": "sound_level" },
{
"id": "32",
"name": "Very High",
"code": "very_high",
"category": "sound_level"
},
{
"id": "33",
"name": "Clicky",
"code": "sound_clicky",
"category": "sound_type"
},
{
"id": "34",
"name": "Thocky",
"code": "sound_thocky",
"category": "sound_type"
},
{
"id": "35",
"name": "Quiet",
"code": "sound_quiet",
"category": "sound_type"
},
{
"id": "36",
"name": "Creamy",
"code": "sound_creamy",
"category": "sound_type"
},
{
"id": "37",
"name": "Clacky",
"code": "sound_clacky",
"category": "sound_type"
},
{
"id": "38",
"name": "Leaf Spring",
"code": "leaf_spring",
"category": "tactility_type"
},
{
"id": "39",
"name": "Coil Spring",
"code": "coil_spring",
"category": "tactility_type"
},
{
"id": "40",
"name": "Click Bar",
"code": "click_bar",
"category": "tactility_type"
},
{
"id": "41",
"name": "Sharp",
"code": "sharp",
"category": "tactility_feedback"
},
{
"id": "42",
"name": "Rounded",
"code": "rounded",
"category": "tactility_feedback"
},
{
"id": "43",
"name": "Crisp",
"code": "crisp",
"category": "tactility_feedback"
},
{
"id": "44",
"name": "Smooth",
"code": "smooth",
"category": "tactility_feedback"
},
{ "id": "45", "name": "Red", "code": "red", "category": "color" },
{ "id": "46", "name": "Black", "code": "black", "category": "color" },
{ "id": "47", "name": "Blue", "code": "blue", "category": "color" },
{ "id": "48", "name": "Brown", "code": "brown", "category": "color" },
{ "id": "49", "name": "Clear", "code": "clear", "category": "color" },
{ "id": "50", "name": "Yellow", "code": "yellow", "category": "color" },
{ "id": "51", "name": "White", "code": "white", "category": "color" },
{
"id": "52",
"name": "Transparent",
"code": "transparent",
"category": "color"
},
{ "id": "53", "name": "Smokey", "code": "smokey", "category": "color" },
{ "id": "54", "name": "Green", "code": "green", "category": "color" },
{ "id": "55", "name": "Purple", "code": "purple", "category": "color" },
{ "id": "56", "name": "Orange", "code": "orange", "category": "color" },
{ "id": "57", "name": "Pink", "code": "pink", "category": "color" },
{ "id": "58", "name": "Gray", "code": "gray", "category": "color" },
{ "id": "59", "name": "Silver", "code": "silver", "category": "color" },
{ "id": "60", "name": "Gold", "code": "gold", "category": "color" },
{ "id": "61", "name": "Turquoise", "code": "turquoise", "category": "color" },
{ "id": "62", "name": "Teal", "code": "teal", "category": "color" },
{ "id": "63", "name": "Lavender", "code": "lavender", "category": "color" },
{ "id": "64", "name": "Magenta", "code": "magenta", "category": "color" },
{ "id": "65", "name": "Cyan", "code": "cyan", "category": "color" },
{ "id": "66", "name": "Ivory", "code": "ivory", "category": "color" },
{ "id": "67", "name": "Coral", "code": "coral", "category": "color" },
{ "id": "68", "name": "Maroon", "code": "maroon", "category": "color" },
{ "id": "69", "name": "Beige", "code": "beige", "category": "color" },
{ "id": "70", "name": "Mint", "code": "mint", "category": "color" },
{ "id": "71", "name": "Peach", "code": "peach", "category": "color" },
{ "id": "72", "name": "Tan", "code": "tan", "category": "color" },
{ "id": "73", "name": "Khaki", "code": "khaki", "category": "color" },
{
"id": "74",
"name": "3-Pin",
"code": "3_pin",
"category": "pin_configuration"
},
{
"id": "75",
"name": "5-Pin",
"code": "5_pin",
"category": "pin_configuration"
}
]
Producers Data
[
{ "id": "1", "name": "Cherry", "alias": "cherry" },
{ "id": "2", "name": "Gateron", "alias": "gateron" },
{ "id": "3", "name": "Kailh", "alias": "kailh" },
{ "id": "4", "name": "Outemu", "alias": "outemu" },
{ "id": "5", "name": "ZealPC", "alias": "zealpc" },
{ "id": "6", "name": "TTC", "alias": "ttc" },
{ "id": "7", "name": "Durock", "alias": "durock" },
{ "id": "8", "name": "Akko", "alias": "akko" },
{ "id": "9", "name": "NovelKeys", "alias": "novelkeys" },
{ "id": "10", "name": "Drop", "alias": "drop" },
{ "id": "11", "name": "Glorious", "alias": "glorious" },
{ "id": "12", "name": "Keychron", "alias": "keychron" },
{ "id": "13", "name": "Epomaker", "alias": "epomaker" },
{ "id": "14", "name": "Razer", "alias": "razer" },
{ "id": "15", "name": "Logitech", "alias": "logitech" },
{ "id": "16", "name": "SteelSeries", "alias": "steelseries" },
{ "id": "17", "name": "Kinetic Labs", "alias": "kentic_labs" },
{ "id": "18", "name": "Chosfox", "alias": "chosfox" },
{ "id": "19", "name": "Roccat", "alias": "roccat" },
{ "id": "20", "name": "Cooler Master", "alias": "cooler_master" },
{ "id": "21", "name": "Wuque Studio", "alias": "wuque_studio" },
{ "id": "22", "name": "JWK", "alias": "jwk" },
{ "id": "23", "name": "Tecsee", "alias": "tecsee" },
{ "id": "24", "name": "Everglide", "alias": "everglide" },
{ "id": "25", "name": "SP-Star", "alias": "sp_star" },
{ "id": "26", "name": "Gazzew", "alias": "gazzew" },
{ "id": "27", "name": "Keydous", "alias": "keydous" },
{ "id": "28", "name": "Cannon Keys", "alias": "cannon_keys" }
{ "id": "29", "name": "KBDFans", "alias": "kbd_fans" },
{ "id": "30", "name": "HMX", "alias": "hmx" },
{ "id": "31", "name": "Tbcats Studio", "alias": "tbcats" },
{ "id": "32", "name": "C³ EQUALZ X TKC", "alias": "c3xtkc" },
]
For each switch provided:
- Ensure that the switch is a real switch, if it is not, just stat that and do no further operations
- Add as much details as possible, if features are not know, skip.
- For each switch, provide is its own entry {}
Details: models.Details{
SpringForce: ptr(float32(45)),
ActuationPoint: ptr(float32(2.0)),
ActuationForce: ptr(float32(45)),
BottomOutForce: ptr(float32(60)),
BottomOutForcePoint: ptr(float32(4.0)),
TotalTravel: ptr(float32(4.0)),
PreTravel: ptr(float32(2.0)),
FactoryLubed: true,
StemMaterialID: ptr(23), // POM
TopHousingMaterialID: ptr(26), // Polycarbonate
BaseHousingMaterialID: ptr(24), // Nylon
SpringMaterialTypeID: ptr(17), // Steel
StemColorID: ptr(45), // Red
TopHousingColorID: ptr(49), // Clear
BottomHousingColorID: ptr(49), // Clear
PinConfigurationID: ptr(74), // 3-Pin
SoundTypeID: ptr(35), // Quiet
SoundLevelID: ptr(28), // Very Low
HasShineThrough: ptr(true),
}