Skip to content

Latest commit

 

History

History
482 lines (457 loc) · 25.5 KB

details.md

File metadata and controls

482 lines (457 loc) · 25.5 KB

Instructions

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

Previous Question and Answers

  1. 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.
  2. Accuracy: Since accuracy is important, should we prioritize official specifications from the manufacturer's website over user-generated content like reviews or forum posts?
  3. 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?
  4. 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)?
  5. 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?
  6. 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.
  7. 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?
  8. 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

Data Structure and References

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"`
}

Switch Details to be in the response

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:

  1. Ensure that the switch is a real switch, if it is not, just stat that and do no further operations
  2. Add as much details as possible, if features are not know, skip.
  3. 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),
}